Updated tests for the context path

without this change the explicit mode is broken and context path scenario can't be tested
    with this change you can provide the EXPLICIT mode with which you can set the RestAssured to send real requests. That way you can set up your application to listen on a socket and have the context path setup. The contracts need to include the context path too since in real world you'll send a request to a URL that contains a context path element.

    fixes #179 #117
This commit is contained in:
Marcin Grzejszczak
2016-12-28 19:38:12 +01:00
parent 0fd91976f3
commit cb803320cd
14 changed files with 377 additions and 92 deletions

View File

@@ -279,6 +279,59 @@ org.springframework.cloud.contract.spec.Contract.make {
}
----
==== Working with Context Paths
Spring Cloud Contract supports context paths.
IMPORTANT: The only thing that changes in order to fully support context paths is the switch
on the *PRODUCER* side. The autogenerated tests need to be using the *EXPLICIT* mode.
The consumer side remains untouched, in order for the generated test to pass you have to switch the *EXPLICIT* mode.
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
<extensions>true</extensions>
<configuration>
<testMode>EXPLICIT</testMode>
</configuration>
</plugin>
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
contracts {
testMode = 'EXPLICIT'
}
----
That way you'll generate a test that *DOES NOT* use MockMvc. It means that you're generating
real requests and you need to setup your generated test's base class to work on a real socket.
Let's imagine the following contract:
[source,groovy,indent=0]
----
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy[tags=context_path_contract,indent=0]
----
Here is an example of how to set up a base class and Rest Assured for everything to work correctly.
[source,groovy,indent=0]
----
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy[tags=context_path_baseclass,indent=0]
----
That way all:
- all your requests in the autogenerated tests will be sent to the real endpoint with your context path included (e.g. `/my-context-path/url`)
- your contracts reflect that you have a context path, thus your generated stubs will also
have that information (e.g. in the stubs you'll see that you have too call `/my-context-path/url`)
==== Messaging Top-Level Elements

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.verifier.builder
import groovy.transform.PackageScope
import groovy.transform.TypeChecked
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
/**
* A {@link JUnitMethodBodyBuilder} implementation that uses Rest Assured in explicit mode
*
* @author Marcin Grzejszczak
*
* @since 1.0.3
*/
@TypeChecked
@PackageScope
class ExplicitJUnitMethodBodyBuilder extends RestAssuredJUnitMethodBodyBuilder {
ExplicitJUnitMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) {
super(stubDefinition, configProperties)
}
@Override
protected String returnedResponseType() {
return "Response"
}
@Override
protected String returnedRequestType() {
return "RequestSpecification"
}
}

View File

@@ -126,16 +126,24 @@ abstract class JUnitMethodBodyBuilder extends RequestProcessingMethodBodyBuilder
@Override
protected String getInputString(Request request) {
def inputString = 'ResponseOptions response = given().spec(request)'
def inputString = "${returnedResponseType()} response = given().spec(request)"
if (response.async){
inputString = inputString + '.when().async()'
}
return inputString
}
protected String returnedResponseType() {
return "ResponseOptions"
}
@Override
protected String getInputString() {
return 'MockMvcRequestSpecification request = given()'
return "${returnedRequestType()} request = given()"
}
protected String returnedRequestType() {
return "MockMvcRequestSpecification"
}
@Override

View File

@@ -22,9 +22,9 @@ import groovy.util.logging.Slf4j
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
import org.springframework.cloud.contract.verifier.config.TestFramework
import org.springframework.cloud.contract.verifier.util.NamesUtil
import org.springframework.cloud.contract.verifier.config.TestMode
import org.springframework.cloud.contract.verifier.file.ContractMetadata
import org.springframework.cloud.contract.verifier.util.NamesUtil
/**
* Builds a test method. Adds an ignore annotation on a method if necessary.
@@ -78,21 +78,26 @@ class MethodBuilder {
private MethodBodyBuilder getMethodBodyBuilder() {
if (stubContent.input || stubContent.outputMessage) {
if (configProperties.targetFramework == TestFramework.JUNIT){
if (configProperties.targetFramework == TestFramework.JUNIT) {
return new JUnitMessagingMethodBodyBuilder(stubContent, configProperties)
}
return new SpockMessagingMethodBodyBuilder(stubContent, configProperties)
}
if (configProperties.testMode == TestMode.MOCKMVC && configProperties.targetFramework == TestFramework.JUNIT){
return new MockMvcJUnitMethodBodyBuilder(stubContent, configProperties)
}
if (configProperties.testMode == TestMode.JAXRSCLIENT) {
if (configProperties.targetFramework == TestFramework.JUNIT){
if (configProperties.targetFramework == TestFramework.JUNIT) {
return new JaxRsClientJUnitMethodBodyBuilder(stubContent, configProperties)
}
return new JaxRsClientSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties)
} else if (configProperties.testMode == TestMode.EXPLICIT) {
if (configProperties.targetFramework == TestFramework.JUNIT) {
return new ExplicitJUnitMethodBodyBuilder(stubContent, configProperties)
}
// in Groovy we're using def so we don't have to update the imports
return new MockMvcSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties)
} else if (configProperties.targetFramework == TestFramework.SPOCK) {
return new MockMvcSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties)
}
return new MockMvcSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties)
return new MockMvcJUnitMethodBodyBuilder(stubContent, configProperties)
}
}

View File

@@ -19,12 +19,8 @@ package org.springframework.cloud.contract.verifier.builder
import groovy.transform.PackageScope
import groovy.transform.TypeChecked
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
import org.springframework.cloud.contract.spec.internal.Header
import org.springframework.cloud.contract.spec.internal.NotToEscapePattern
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
import java.util.regex.Pattern
/**
* A {@link JUnitMethodBodyBuilder} implementation that uses MockMvc to send requests.
*
@@ -34,55 +30,20 @@ import java.util.regex.Pattern
*/
@TypeChecked
@PackageScope
class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder {
class MockMvcJUnitMethodBodyBuilder extends RestAssuredJUnitMethodBodyBuilder {
MockMvcJUnitMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) {
super(stubDefinition, configProperties)
}
@Override
protected void validateResponseCodeBlock(BlockBuilder bb) {
bb.addLine("assertThat(response.statusCode()).isEqualTo($response.status.serverValue);")
protected String returnedResponseType() {
return "ResponseOptions"
}
@Override
protected void validateResponseHeadersBlock(BlockBuilder bb) {
response.headers?.executeForEachHeader { Header header ->\
processHeaderElement(bb, header.name, header.serverValue)
}
}
@Override
protected String getResponseBodyPropertyComparisonString(String property, Object value) {
return null
}
@Override
protected String getResponseBodyPropertyComparisonString(String property, Pattern value) {
return null
}
@Override
protected void processHeaderElement(BlockBuilder blockBuilder, String property, Object value) {
if (value instanceof NotToEscapePattern) {
blockBuilder.addLine("assertThat(response.header(\"$property\"))." +
"${createMatchesMethod(value.serverValue.pattern().replace("\\", "\\\\"))};")
}
}
@Override
protected void processHeaderElement(BlockBuilder blockBuilder, String property, String value) {
blockBuilder.addLine("assertThat(response.header(\"$property\")).${createHeaderComparison(value)}")
}
@Override
protected void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern pattern) {
blockBuilder.addLine("assertThat(response.header(\"$property\")).${createHeaderComparison(pattern)}")
}
@Override
protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) {
blockBuilder.addLine("${exec.insertValue("response.header(\"$property\")")};")
protected String returnedRequestType() {
return "MockMvcRequestSpecification"
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.verifier.builder
import groovy.transform.PackageScope
import groovy.transform.TypeChecked
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
import org.springframework.cloud.contract.spec.internal.Header
import org.springframework.cloud.contract.spec.internal.NotToEscapePattern
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
import java.util.regex.Pattern
/**
* A {@link JUnitMethodBodyBuilder} implementation that uses Rest Assured.
*
* @author Marcin Grzejszczak
*
* @since 1.0.3
*/
@TypeChecked
@PackageScope
class RestAssuredJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder {
RestAssuredJUnitMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) {
super(stubDefinition, configProperties)
}
@Override
protected void validateResponseCodeBlock(BlockBuilder bb) {
bb.addLine("assertThat(response.statusCode()).isEqualTo($response.status.serverValue);")
}
@Override
protected void validateResponseHeadersBlock(BlockBuilder bb) {
response.headers?.executeForEachHeader { Header header ->\
processHeaderElement(bb, header.name, header.serverValue)
}
}
@Override
protected String getResponseBodyPropertyComparisonString(String property, Object value) {
return null
}
@Override
protected String getResponseBodyPropertyComparisonString(String property, Pattern value) {
return null
}
@Override
protected void processHeaderElement(BlockBuilder blockBuilder, String property, Object value) {
if (value instanceof NotToEscapePattern) {
blockBuilder.addLine("assertThat(response.header(\"$property\"))." +
"${createMatchesMethod(value.serverValue.pattern().replace("\\", "\\\\"))};")
}
}
@Override
protected void processHeaderElement(BlockBuilder blockBuilder, String property, String value) {
blockBuilder.addLine("assertThat(response.header(\"$property\")).${createHeaderComparison(value)}")
}
@Override
protected void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern pattern) {
blockBuilder.addLine("assertThat(response.header(\"$property\")).${createHeaderComparison(pattern)}")
}
@Override
protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) {
blockBuilder.addLine("${exec.insertValue("response.header(\"$property\")")};")
}
}

View File

@@ -94,6 +94,9 @@ class SingleTestGenerator {
if (contracts.values().contains(TestType.HTTP) && configProperties.testMode == TestMode.MOCKMVC) {
clazz.addImport('com.jayway.restassured.module.mockmvc.specification.MockMvcRequestSpecification')
clazz.addImport('com.jayway.restassured.response.ResponseOptions')
} else if (contracts.values().contains(TestType.HTTP) && configProperties.testMode == TestMode.EXPLICIT) {
clazz.addImport('com.jayway.restassured.specification.RequestSpecification')
clazz.addImport('com.jayway.restassured.response.Response')
}
clazz.addImport('org.junit.Test')
clazz.addStaticImport('org.assertj.core.api.Assertions.assertThat')

View File

@@ -1,7 +1,7 @@
/*
* Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
@@ -21,6 +21,7 @@ import org.junit.rules.TemporaryFolder
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
import org.springframework.cloud.contract.verifier.config.TestMode
import org.springframework.cloud.contract.verifier.file.ContractMetadata
import org.springframework.cloud.contract.verifier.util.SyntaxChecker
import spock.lang.Issue
import spock.lang.Specification
@@ -33,16 +34,44 @@ class SingleTestGeneratorSpec extends Specification {
TemporaryFolder tmpFolder = new TemporaryFolder()
File file
static List<String> jUnitClassStrings = ['package test;', 'import com.jayway.jsonpath.DocumentContext;', 'import com.jayway.jsonpath.JsonPath;',
'import org.junit.FixMethodOrder;', 'import org.junit.Ignore;', 'import org.junit.Test;', 'import org.junit.runners.MethodSorters;',
'import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson;', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*;',
'@FixMethodOrder(MethodSorters.NAME_ASCENDING)', '@Test', '@Ignore', 'mport com.jayway.restassured.module.mockmvc.specification.MockMvcRequestSpecification;',
'import com.jayway.restassured.response.ResponseOptions;', 'import static org.assertj.core.api.Assertions.assertThat;']
private static final List<String> mockMvcJUnitClassStrings = ['package test; ', 'import com.jayway.jsonpath.DocumentContext; ', 'import com.jayway.jsonpath.JsonPath; ',
'import org.junit.FixMethodOrder; ', 'import org.junit.Ignore; ', 'import org.junit.Test; ', 'import org.junit.runners.MethodSorters; ',
'import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson; ', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*; ',
'@FixMethodOrder(MethodSorters.NAME_ASCENDING); ', '@Test; ', '@Ignore; ', 'import com.jayway.restassured.module.mockmvc.specification.MockMvcRequestSpecification; ',
'import com.jayway.restassured.response.ResponseOptions; ', 'import static org.assertj.core.api.Assertions.assertThat']
static List<String> spockClassStrings = ['package test', 'import com.jayway.jsonpath.DocumentContext', 'import com.jayway.jsonpath.JsonPath',
'import spock.lang.Ignore', 'import spock.lang.Specification', 'import spock.lang.Stepwise',
'import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*',
'@Stepwise', '@Ignore']
private static final List<String> explicitJUnitClassStrings = ['package test; ', 'import com.jayway.jsonpath.DocumentContext; ', 'import com.jayway.jsonpath.JsonPath; ',
'import org.junit.FixMethodOrder; ', 'import org.junit.Ignore; ', 'import org.junit.Test; ', 'import org.junit.runners.MethodSorters; ',
'import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson; ', 'import static com.jayway.restassured.RestAssured.*; ',
'@FixMethodOrder(MethodSorters.NAME_ASCENDING); ', '@Test; ', '@Ignore; ', 'import com.jayway.restassured.specification.RequestSpecification; ',
'import com.jayway.restassured.response.Response; ', 'import static org.assertj.core.api.Assertions.assertThat']
private static final List<String> spockClassStrings = ['package test', 'import com.jayway.jsonpath.DocumentContext', 'import com.jayway.jsonpath.JsonPath',
'import spock.lang.Ignore', 'import spock.lang.Specification', 'import spock.lang.Stepwise',
'import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*',
'@Stepwise', '@Ignore']
private static final List<String> explicitSpockClassStrings = ['package test', 'import com.jayway.jsonpath.DocumentContext', 'import com.jayway.jsonpath.JsonPath',
'import spock.lang.Ignore', 'import spock.lang.Specification', 'import spock.lang.Stepwise',
'import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson', 'import static com.jayway.restassured.RestAssured.*',
'@Stepwise', '@Ignore']
public static final Closure JAVA_ASSERTER = { String classToTest ->
String name = Math.abs(new Random().nextInt())
String changedTest = classToTest.replace("public class Test", "public class Test${name}")
SyntaxChecker.tryToCompileJavaWithoutImports("test.Test${name}", changedTest)
}
public static final Closure JAVA_JAXRS_ASSERTER = { String classToTest ->
String name = Math.abs(new Random().nextInt())
String changedTest = classToTest.replace("public class Test {", "public class Test${name} {\njavax.ws.rs.client.WebTarget webTarget;\n")
SyntaxChecker.tryToCompileJavaWithoutImports("test.Test${name}", changedTest)
}
public static final Closure GROOVY_ASSERTER = { String classToTest ->
SyntaxChecker.tryToCompileGroovyWithoutImports(classToTest)
}
def setup() {
file = tmpFolder.newFile()
@@ -59,9 +88,9 @@ class SingleTestGeneratorSpec extends Specification {
""")
}
def "should build MockMvc test class for #testFramework"() {
def "should build test class for #testFramework"() {
given:
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties()
properties.targetFramework = testFramework
ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2)
contract.ignored >> true
@@ -73,16 +102,19 @@ class SingleTestGeneratorSpec extends Specification {
then:
classStrings.each { clazz.contains(it) }
and:
asserter(clazz)
where:
testFramework | classStrings
JUNIT | jUnitClassStrings
SPOCK | spockClassStrings
testFramework | mode | classStrings | asserter
JUNIT | TestMode.MOCKMVC | mockMvcJUnitClassStrings | JAVA_ASSERTER
JUNIT | TestMode.EXPLICIT | explicitJUnitClassStrings | JAVA_ASSERTER
SPOCK | TestMode.MOCKMVC | spockClassStrings | GROOVY_ASSERTER
SPOCK | TestMode.EXPLICIT | explicitSpockClassStrings | GROOVY_ASSERTER
}
def "should build JaxRs test class for #testFramework"() {
given:
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties()
properties.testMode = TestMode.JAXRSCLIENT
properties.targetFramework = testFramework
ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2)
@@ -96,10 +128,13 @@ class SingleTestGeneratorSpec extends Specification {
then:
classStrings.each { clazz.contains(it) }
and:
asserter(clazz)
where:
testFramework | classStrings
JUNIT | ['import static javax.ws.rs.client.Entity.*;', 'import javax.ws.rs.core.Response;']
SPOCK | ['import static javax.ws.rs.client.Entity.*;']
testFramework | classStrings | asserter
JUNIT | ['import static javax.ws.rs.client.Entity.*', 'import javax.ws.rs.core.Response'] | JAVA_JAXRS_ASSERTER
SPOCK | ['import static javax.ws.rs.client.Entity.*'] | GROOVY_ASSERTER
}
def "should work if there is messaging and rest in one folder #testFramework"() {
@@ -116,12 +151,12 @@ class SingleTestGeneratorSpec extends Specification {
messageHeaders {
header('sample', 'header')
}
assertThat('bookWasDeleted()')
assertThat('hashCode()')
}
}
""")
and:
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties()
properties.targetFramework = testFramework
ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2)
contract.ignored >> true
@@ -140,10 +175,13 @@ class SingleTestGeneratorSpec extends Specification {
classStrings.each { clazz.contains(it) }
clazz.contains('@Inject ContractVerifierMessaging')
and:
asserter(clazz)
where:
testFramework | classStrings
JUNIT | jUnitClassStrings
SPOCK | spockClassStrings
testFramework | classStrings | asserter
JUNIT | mockMvcJUnitClassStrings | JAVA_ASSERTER
SPOCK | spockClassStrings | GROOVY_ASSERTER
}
@Issue('#30')
@@ -163,7 +201,7 @@ class SingleTestGeneratorSpec extends Specification {
}
""")
and:
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties()
properties.targetFramework = testFramework
and:
ContractMetadata contract2 = new ContractMetadata(secondFile.toPath(), true, 1, 2)
@@ -179,10 +217,68 @@ class SingleTestGeneratorSpec extends Specification {
classStrings.each { clazz.contains(it) }
clazz.contains('@Ignore')
and:
asserter(clazz)
where:
testFramework | classStrings
JUNIT | jUnitClassStrings
SPOCK | spockClassStrings
testFramework | classStrings | asserter
JUNIT | mockMvcJUnitClassStrings | JAVA_ASSERTER
SPOCK | spockClassStrings | GROOVY_ASSERTER
}
@Issue('#117')
def "should generate test in explicit test mode using JUnit"() {
given:
String baseClass = """
// tag::context_path_baseclass[]
import com.jayway.restassured.RestAssured;
import org.junit.Before;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(classes = ContextPathTestingBaseClass.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ContextPathTestingBaseClass {
@LocalServerPort int port;
@Before
public void setup() {
RestAssured.baseURI = "http://localhost";
RestAssured.port = this.port;
}
}
// end::context_path_baseclass[]
"""
SyntaxChecker.tryToCompileJavaWithoutImports("test.ContextPathTestingBaseClass", "package test;\n${baseClass}")
and:
File secondFile = tmpFolder.newFile()
secondFile.write("""
// tag::context_path_contract[]
org.springframework.cloud.contract.spec.Contract.make {
request {
method 'GET'
url '/my-context-path/url'
}
response {
status 200
}
}
// end::context_path_contract[]
""")
and:
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties()
properties.targetFramework = JUNIT
properties.testMode = TestMode.EXPLICIT
properties.baseClassForTests = "test.ContextPathTestingBaseClass"
and:
ContractMetadata contract = new ContractMetadata(file.toPath(), false, 1, null)
and:
SingleTestGenerator testGenerator = new SingleTestGenerator(properties)
when:
String clazz = testGenerator.buildClass([contract], "test", "test", 'com/foo')
then:
clazz.contains("RequestSpecification request = given();")
clazz.contains("Response response = given().spec(request)")
}

View File

@@ -43,7 +43,7 @@ class SyntaxChecker {
].collect { "import static ${it};"}.join("\n")
public static void tryToCompile(String builderName, String test) {
static void tryToCompile(String builderName, String test) {
if (builderName.toLowerCase().contains("spock")) {
tryToCompileGroovy(test)
} else {
@@ -51,7 +51,7 @@ class SyntaxChecker {
}
}
public static void tryToCompileGroovy(String test) {
static void tryToCompileGroovy(String test) {
def imports = new ImportCustomizer()
CompilerConfiguration configuration = new CompilerConfiguration()
configuration.addCompilationCustomizers(imports)
@@ -65,7 +65,7 @@ class SyntaxChecker {
new GroovyShell(SyntaxChecker.classLoader, configuration).parse(sourceCode.toString())
}
public static Class tryToCompileJava(String test) {
static Class tryToCompileJava(String test) {
Random random = new Random()
int first = Math.abs(random.nextInt())
int hashCode = Math.abs(test.hashCode())
@@ -76,15 +76,25 @@ class SyntaxChecker {
sourceCode.append("${DEFAULT_IMPORTS_AS_STRING}\n")
sourceCode.append("${STATIC_IMPORTS}\n")
sourceCode.append("\n")
sourceCode.append("public class ${className} {\n")
sourceCode.append("class ${className} {\n")
sourceCode.append("\n")
sourceCode.append(" WebTarget webTarget;")
sourceCode.append("\n")
sourceCode.append(" public void method() {\n")
sourceCode.append(" void method() {\n")
sourceCode.append(" ${test}\n")
sourceCode.append(" }\n")
sourceCode.append("}")
return InMemoryJavaCompiler.compile(fqnClassName, sourceCode.toString())
}
static boolean tryToCompileJavaWithoutImports(String fqn, String test) {
InMemoryJavaCompiler.compile(fqn, test)
return true
}
static boolean tryToCompileGroovyWithoutImports(String test) {
new GroovyShell(SyntaxChecker.classLoader).parse(test)
return true
}
}

View File

@@ -4,12 +4,14 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.contract.stubrunner.StubFinder;
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
import com.example.loan.model.Client;
import com.example.loan.model.LoanApplication;
@@ -20,19 +22,28 @@ import static org.assertj.core.api.Assertions.assertThat;
// tag::autoconfigure_stubrunner[]
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.NONE)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
@AutoConfigureStubRunner(repositoryRoot = "classpath:m2repo/repository/",
ids = { "org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer" })
ids = { "org.springframework.cloud.contract.verifier.stubs:contextPathFraudDetectionServer" })
@DirtiesContext
public class LoanApplicationServiceTests {
// end::autoconfigure_stubrunner[]
@Autowired private LoanApplicationService service;
@Autowired private StubFinder stubFinder;
@LocalServerPort Integer port;
@Before
public void setPort() {
this.service.setFraudUrl(this.stubFinder.findStubUrl("fraudDetectionServer").toString());
this.service.setFraudUrl(this.stubFinder.findStubUrl("contextPathFraudDetectionServer").toString() + "/fraud-path/");
}
@Test
public void shouldStartThisAppWithContextPath() {
String response = new RestTemplate()
.getForObject("http://localhost:" + this.port + "/my-path/health", String.class);
assertThat(response).isNotEmpty();
}
@Test

View File

@@ -19,7 +19,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.cloud.contract.verifier.stubs</groupId>
<artifactId>fraudDetectionServer</artifactId>
<artifactId>contextPathFraudDetectionServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
</project>

View File

@@ -17,7 +17,7 @@
<metadata>
<groupId>org.springframework.cloud.contract.verifier.stubs</groupId>
<artifactId>fraudDetectionServer</artifactId>
<artifactId>contextPathFraudDetectionServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<versioning>
<versions>