Tests are not being generated based on contracts in java. I used gradle to configure spring-cloud-contract and used java for contracts. When I run ./gradlew clean build -x test
, it throws illegal state exception because of absence of contract tests which I configured in build.gradle (throw new IllegalStateException("No tests were found. Failing the build")).
build.gradle:
contracts {
contractsDslDir = file("src/test/resources/contracts")
testFramework = "JUNIT"
packageWithBaseClasses = 'com.epam.training.microservicefoundation.resourceservice'
baseClassMappings {
baseClassMapping(".rest.*", "com.epam.training.microservicefoundation.resourceservice.RestBase")
}
contractsDslDir = new File(project.rootDir, "src/test/java/contracts")
}
contractTest {
useJUnitPlatform()
testLogging {
exceptionFormat = 'full'
}
afterSuite { desc, result ->
if (!desc.parent) {
println "Results: (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)"
boolean skipTests = Boolean.parseBoolean(project.findProperty('SKIP_TESTS') ?: "false")
if (result.testCount == 0 && !skipTests) {
throw new IllegalStateException("No tests were found. Failing the build")
}
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
artifact bootJar
artifact verifierStubsJar
// https://github.com/spring-gradle-plugins/dependency-management-plugin/issues/273
versionMapping {
usage("java-api") {
fromResolutionOf("runtimeClasspath")
}
usage("java-runtime") {
fromResolutionResult()
}
}
}
}
}
contract in java:
public class shouldGet implements Supplier<Contract> {
@Override
public Contract get() {
return Contract.make(contract -> {
contract.request(request -> {
request.method("GET");
request.url("/api/v1/resources/123");
request.headers(headers -> headers.accept(ResourceType.MP3.getMimeType()));
});
contract.response(response -> {
response.status(response.OK());
response.body(response.fileAsBytes("resources/files/mpthreetest.mp3"));
response.headers(headers -> headers.contentType(ResourceType.MP3.getMimeType()));
});
});
}
}
base class for generated class by producer:
public abstract class RestBase {
ResourceController resourceController;
@BeforeEach
public void setup() {
resourceController = new ResourceController(new FakeResourceService());
EncoderConfig encoderConfig = new EncoderConfig().appendDefaultContentCharsetToContentTypeIfUndefined(false);
RestAssuredMockMvc.config = new RestAssuredMockMvcConfig().encoderConfig(encoderConfig);
RestAssuredMockMvc.standaloneSetup(resourceController);
}
static class FakeResourceService implements ResourceService {
@Override
public ResourceRecord save(MultipartFile file) {
return null;
}
@Override
public InputStreamResource getById(long id) {
try {
File file = ResourceUtils.getFile("classpath:files/mpthreetest.mp3");
return new InputStreamResource(new FileInputStream(file));
} catch (FileNotFoundException ex) {
return null;
}
}
@Override
public List<ResourceRecord> deleteByIds(long[] ids) {
return null;
}
}
}
output of generated tests in build file:
@SuppressWarnings("rawtypes")
public class RestTest extends RestBase {
}
there is no any test generated, but there should be corresponding test based on contract shouldGet.java
I realized that the issue was related to the response body in the contract: response.body(response.fileAsBytes("resources/files/mpthreetest.mp3"));
Apparently it could not read from the resources folder, after I move the file to the same package where the contract file located, then the issue was resolved successfully:
And, changed the response body to response.body(response.fileAsBytes("mpthreetest.mp3"));
P.S: Using Supplier<Collection<Contract>>
interface also might prevent the contract to get generated, I changed it to just Supplier<Contract>