@@ -289,6 +289,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
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -83,6 +83,9 @@ class JavaTestGenerator implements 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')
|
||||
|
||||
@@ -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.
|
||||
@@ -92,21 +92,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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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\")")};")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -34,16 +35,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()
|
||||
@@ -60,9 +89,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, convertAsCollection(file))
|
||||
contract.ignored >> true
|
||||
@@ -74,16 +103,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, convertAsCollection(file))
|
||||
@@ -97,10 +129,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"() {
|
||||
@@ -117,12 +152,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, convertAsCollection(file))
|
||||
contract.ignored >> true
|
||||
@@ -141,10 +176,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')
|
||||
@@ -164,7 +202,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, convertAsCollection(file))
|
||||
@@ -180,10 +218,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)")
|
||||
}
|
||||
|
||||
def "should pick the contract's name as the test method"() {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user