diff --git a/docs/src/main/asciidoc/verifier/contract.adoc b/docs/src/main/asciidoc/verifier/contract.adoc
index 4aece20bef..3733ad09f5 100644
--- a/docs/src/main/asciidoc/verifier/contract.adoc
+++ b/docs/src/main/asciidoc/verifier/contract.adoc
@@ -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
+----
+
+ org.springframework.cloud
+ spring-cloud-contract-maven-plugin
+ ${spring-cloud-contract.version}
+ true
+
+ EXPLICIT
+
+
+----
+
+[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
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ExplicitJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ExplicitJUnitMethodBodyBuilder.groovy
new file mode 100644
index 0000000000..09baadc1fd
--- /dev/null
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ExplicitJUnitMethodBodyBuilder.groovy
@@ -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"
+ }
+
+}
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy
index fcdc08057a..a41ec6d2e9 100644
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy
@@ -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
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy
index 60927dde38..eacb50f2b3 100644
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy
@@ -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)
}
}
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy
index f9bdd6f6cb..ef9d17ffd7 100644
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy
@@ -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"
}
}
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RestAssuredJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RestAssuredJUnitMethodBodyBuilder.groovy
new file mode 100644
index 0000000000..52e6741f88
--- /dev/null
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RestAssuredJUnitMethodBodyBuilder.groovy
@@ -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\")")};")
+ }
+
+}
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy
index 0109024833..3b051848f0 100644
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy
@@ -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')
diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy
index 8db73be660..5fa08b4f7e 100644
--- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy
+++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy
@@ -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 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 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 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 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 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 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)")
}
diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/SyntaxChecker.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/SyntaxChecker.groovy
index e4f0d39f16..07493e1b37 100644
--- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/SyntaxChecker.groovy
+++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/SyntaxChecker.groovy
@@ -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
+ }
+
}
diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/test/java/com/example/loan/LoanApplicationServiceTests.java b/tests/spring-cloud-contract-stub-runner-context-path/src/test/java/com/example/loan/LoanApplicationServiceTests.java
index 0fae64d3da..5910bd9dcd 100644
--- a/tests/spring-cloud-contract-stub-runner-context-path/src/test/java/com/example/loan/LoanApplicationServiceTests.java
+++ b/tests/spring-cloud-contract-stub-runner-context-path/src/test/java/com/example/loan/LoanApplicationServiceTests.java
@@ -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
diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/contextPathFraudDetectionServer/0.0.1-SNAPSHOT/contextPathFraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/contextPathFraudDetectionServer/0.0.1-SNAPSHOT/contextPathFraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar
new file mode 100644
index 0000000000..5dccb5df1c
Binary files /dev/null and b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/contextPathFraudDetectionServer/0.0.1-SNAPSHOT/contextPathFraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar differ
diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/contextPathFraudDetectionServer/0.0.1-SNAPSHOT/contextPathFraudDetectionServer-0.0.1-SNAPSHOT.pom
similarity index 94%
rename from tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom
rename to tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/contextPathFraudDetectionServer/0.0.1-SNAPSHOT/contextPathFraudDetectionServer-0.0.1-SNAPSHOT.pom
index 40610c8cdb..02a7f412cb 100644
--- a/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom
+++ b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/contextPathFraudDetectionServer/0.0.1-SNAPSHOT/contextPathFraudDetectionServer-0.0.1-SNAPSHOT.pom
@@ -19,7 +19,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4.0.0
org.springframework.cloud.contract.verifier.stubs
- fraudDetectionServer
+ contextPathFraudDetectionServer
0.0.1-SNAPSHOT
pom
diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/contextPathFraudDetectionServer/maven-metadata.xml
similarity index 94%
rename from tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml
rename to tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/contextPathFraudDetectionServer/maven-metadata.xml
index 281b9b3b80..668142b2f3 100644
--- a/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml
+++ b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/contextPathFraudDetectionServer/maven-metadata.xml
@@ -17,7 +17,7 @@
org.springframework.cloud.contract.verifier.stubs
- fraudDetectionServer
+ contextPathFraudDetectionServer
0.0.1-SNAPSHOT
diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar
deleted file mode 100644
index fdb70e383f..0000000000
Binary files a/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar and /dev/null differ