diff --git a/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy b/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy
index 63dff2b..5c3af82 100644
--- a/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy
+++ b/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy
@@ -16,7 +16,6 @@ class ContextExecutor {
this.mocks = new CopyOnWriteArrayList<>([initialMock])
httpServerWraper.createContext(path,{
HttpExchange ex ->
- ex.sendResponseHeaders(200, 0)
String input = ex.requestBody.text
println "Mock received input"
GPathResult inputXml = new XmlSlurper().parseText(input)
@@ -31,6 +30,7 @@ class ContextExecutor {
}
}
if (xml != null && mock.predicate(xml)) {
+ ex.sendResponseHeaders(mock.statusCode, 0)
println "Mock ${mock.name} invoked"
++mock.counter
String response = mock.responseOk(xml)
@@ -42,6 +42,7 @@ class ContextExecutor {
e.printStackTrace()
}
}
+ ex.sendResponseHeaders(404, 0)
ex.responseBody << ""
ex.responseBody.close()
})
diff --git a/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy b/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy
index f79c0e0..a2d6245 100644
--- a/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy
+++ b/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy
@@ -17,7 +17,6 @@ class HttpMockServer {
httpServerWraper.createContext('/serverControl', {
HttpExchange ex ->
- ex.sendResponseHeaders(200, 0)
try{
GPathResult request = new XmlSlurper().parse(ex.requestBody)
if(ex.requestMethod== 'POST' && request.name() == 'addMock'){
@@ -41,10 +40,23 @@ class HttpMockServer {
println "Adding $name"
String mockPath = request.path
int mockPort = Integer.valueOf(request.port as String)
- Closure predicate = Eval.me(request.predicate as String) as Closure
- Closure okResponse = Eval.me(request.response as String) as Closure
- boolean soap = Boolean.valueOf(request.soap as String)
- Mock mock = new Mock(name, mockPath, mockPort, predicate, okResponse, soap)
+ Mock mock = new Mock(name, mockPath, mockPort)
+ String predicate = request.predicate
+ if(predicate){
+ mock.predicate = Eval.me(predicate) as Closure
+ }
+ String okResponse = request.response
+ if(okResponse){
+ mock.responseOk = Eval.me(okResponse) as Closure
+ }
+ String soap = request.soap
+ if(soap){
+ mock.soap = Boolean.valueOf(soap)
+ }
+ String statusCode = request.statusCode
+ if(statusCode){
+ mock.statusCode = Integer.valueOf(statusCode)
+ }
HttpServerWraper child = childServers.find { it.port == mockPort }
if (!child) {
child = new HttpServerWraper(mockPort)
@@ -52,6 +64,7 @@ class HttpMockServer {
}
child.addMock(mockPath, mock)
mockNames << name
+ ex.sendResponseHeaders(200, 0)
ex.responseBody << ''
ex.responseBody.close()
}
@@ -64,11 +77,13 @@ class HttpMockServer {
println "Removing $name"
int used = childServers.inject(0) { int res, HttpServerWraper server-> server.removeMock(name) + res}
mockNames.remove(name)
+ ex.sendResponseHeaders(200, 0)
ex.responseBody << "$used"
ex.responseBody.close()
}
private static void createErrorResponse(HttpExchange ex, Exception e) {
+ ex.sendResponseHeaders(400, 0)
ex.responseBody << """${e.message}"""
ex.responseBody.close()
}
diff --git a/src/main/groovy/pl/touk/mockserver/server/Mock.groovy b/src/main/groovy/pl/touk/mockserver/server/Mock.groovy
index c36e567..e250616 100644
--- a/src/main/groovy/pl/touk/mockserver/server/Mock.groovy
+++ b/src/main/groovy/pl/touk/mockserver/server/Mock.groovy
@@ -7,21 +7,18 @@ class Mock {
final String name
final String path
final int port
- final Closure predicate
- final Closure responseOk
- final boolean soap
- //TODO add http method
- //TODO add http code
- //TODO add request headers
- //TODO add response headers
+ Closure predicate = { xml -> true }
+ Closure responseOk = { xml -> '' }
+ boolean soap = false
+ int statusCode = 200
+ //TODO add http method - default POST
+ //TODO add request headers - default [:]
+ //TODO add response headers - default [:]
int counter = 0
//TODO add historical invocations
- Mock(String name, String path, int port, Closure predicate, Closure responseOk, boolean soap) {
+ Mock(String name, String path, int port) {
this.name = name
- this.predicate = predicate
- this.responseOk = responseOk
- this.soap = soap
this.path = path
this.port = port
}
diff --git a/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy b/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy
index 893332f..3cf3c02 100644
--- a/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy
+++ b/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy
@@ -9,6 +9,7 @@ class AddMockRequestData {
String predicate
String response
Boolean soap
+ Integer statusCode
void setPredicate(String predicate){
this.predicate = StringEscapeUtils.escapeXml11(predicate)
diff --git a/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy b/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy
index 994f829..3b56c38 100644
--- a/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy
+++ b/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy
@@ -16,46 +16,50 @@ class ControlServerClient {
address = "http://$host:$port/serverControl"
}
- void addMock(AddMockRequestData addMockRequestData){
+ void addMock(AddMockRequestData addMockRequestData) {
HttpPost addMockPost = new HttpPost(address)
addMockPost.entity = buildAddMockRequest(addMockRequestData)
CloseableHttpResponse response = client.execute(addMockPost)
GPathResult responseXml = Util.extractXmlResponse(response)
- if(responseXml.name() != 'mockAdded'){
- throw new MockAlreadyExists()
+ if (responseXml.name() != 'mockAdded') {
+ if (responseXml.text() == 'mock already registered') {
+ throw new MockAlreadyExists()
+
+ }
+ throw new InvalidMockDefinitionException(responseXml.text())
}
}
- int removeMock(String name){
+ int removeMock(String name) {
HttpPost removeMockPost = new HttpPost(address)
- removeMockPost.entity = buildRemoveMockRequest(new RemoveMockRequestData(name:name))
+ removeMockPost.entity = buildRemoveMockRequest(new RemoveMockRequestData(name: name))
CloseableHttpResponse response = client.execute(removeMockPost)
GPathResult responseXml = Util.extractXmlResponse(response)
- if(responseXml.name() == 'mockRemoved'){
+ if (responseXml.name() == 'mockRemoved') {
return responseXml.text() as int
}
throw new MockDoesNotExist()
}
-
- private StringEntity buildRemoveMockRequest(RemoveMockRequestData data){
+ private static StringEntity buildRemoveMockRequest(RemoveMockRequestData data) {
return new StringEntity("""\
${data.name}
- """,ContentType.create("text/xml", "UTF-8"))
+ """, ContentType.create("text/xml", "UTF-8"))
}
- private StringEntity buildAddMockRequest(AddMockRequestData data){
+ private static StringEntity buildAddMockRequest(AddMockRequestData data) {
return new StringEntity("""\
${data.name}
${data.path}
${data.port}
- ${data.predicate}
- ${data.response}
- ${data.soap}
+ ${data.predicate != null ? "${data.predicate}" : ''}
+ ${data.response != null ? "${data.response}" : ''}
+ ${data.soap != null ? "${data.soap}" : ''}
+ ${data.statusCode != null ? "${data.statusCode}" : ''}
- """,ContentType.create("text/xml", "UTF-8"))
+ """, ContentType.create("text/xml", "UTF-8"))
}
}
diff --git a/src/test/groovy/pl/touk/mockserver/client/InvalidMockDefinitionException.groovy b/src/test/groovy/pl/touk/mockserver/client/InvalidMockDefinitionException.groovy
new file mode 100644
index 0000000..96156a1
--- /dev/null
+++ b/src/test/groovy/pl/touk/mockserver/client/InvalidMockDefinitionException.groovy
@@ -0,0 +1,7 @@
+package pl.touk.mockserver.client
+
+class InvalidMockDefinitionException extends RuntimeException{
+ InvalidMockDefinitionException(String s) {
+ super(s)
+ }
+}
diff --git a/src/test/groovy/pl/touk/mockserver/server/MockServerIntegrationTest.groovy b/src/test/groovy/pl/touk/mockserver/server/MockServerIntegrationTest.groovy
index 5738ce3..63e2538 100644
--- a/src/test/groovy/pl/touk/mockserver/server/MockServerIntegrationTest.groovy
+++ b/src/test/groovy/pl/touk/mockserver/server/MockServerIntegrationTest.groovy
@@ -7,6 +7,7 @@ import org.apache.http.entity.ContentType
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
+import org.apache.http.util.EntityUtils
import pl.touk.mockserver.client.*
import spock.lang.Shared
import spock.lang.Specification
@@ -73,7 +74,7 @@ class MockServerIntegrationTest extends Specification {
controlServerClient.removeMock('testSoap') == 1
}
- def "should not remove when it does not exist"() {
+ def "should not remove mock when it does not exist"() {
when:
controlServerClient.removeMock('testSoap')
then:
@@ -214,9 +215,62 @@ class MockServerIntegrationTest extends Specification {
9998 | '/test2' | 'another port and path'
}
- //TODO def "should get mock report"(){}
- //TODO def "should get list mocks"(){}
- //TODO def "should dispatch rest mock with response code"(){}
+ @Unroll
+ def "should dispatch rest mock with response code"() {
+ given:
+ controlServerClient.addMock(new AddMockRequestData(
+ name: 'testRest1',
+ path: '/test1',
+ port: 9999,
+ statusCode: statusCode
+ ))
+ HttpPost request = new HttpPost('http://localhost:9999/test1')
+ request.entity = new StringEntity('', ContentType.create("text/xml", "UTF-8"))
+ when:
+ CloseableHttpResponse response = client.execute(request)
+ then:
+ response.statusLine.statusCode == expectedStatusCode
+ EntityUtils.consumeQuietly(response.entity)
+ where:
+ statusCode | expectedStatusCode
+ null | 200
+ 300 | 300
+ 204 | 204
+ }
+
+ def "should return response code 404 and error body when mocks does not apply"() {
+ given:
+ controlServerClient.addMock(new AddMockRequestData(
+ name: 'testRest1',
+ path: '/test1',
+ port: 9999,
+ predicate: '''{xml -> xml.name() == 'request2'}''',
+ response: '''{xml -> ""}'''
+ ))
+ HttpPost request = new HttpPost('http://localhost:9999/test1')
+ request.entity = new StringEntity('', ContentType.create("text/xml", "UTF-8"))
+ when:
+ CloseableHttpResponse response = client.execute(request)
+ then:
+ response.statusLine.statusCode == 404
+ GPathResult secondXmlResponse = Util.extractXmlResponse(response)
+ secondXmlResponse.name() == 'invalidInput'
+ }
+
+ def "should inform that there was problem during adding mock - invalid port"(){
+ when:
+ controlServerClient.addMock(new AddMockRequestData(
+ name: 'testSoap',
+ path: '/testEndpoint2',
+ port: -1,
+ predicate: '''{xml -> true}''',
+ response: '''{xml -> ""}''',
+ soap: true
+ ))
+ then:
+ thrown(InvalidMockDefinitionException)
+ }
+
//TODO def "should dispatch rest mock with post method"(){}
//TODO def "should dispatch rest mock with post method and request headers"(){}
//TODO def "should dispatch rest mock with post method and response headers"(){}
@@ -230,4 +284,8 @@ class MockServerIntegrationTest extends Specification {
//TODO def "should dispatch rest mock with delete method and request headers"(){}
//TODO def "should dispatch rest mock with delete method and response headers"(){}
//TODO def "should dispatch rest mocks with all methods"(){}
+
+ //TODO def "should get mock report"(){}
+ //TODO def "should get list mocks"(){}
+ //TODO def "should validate mock when creating"
}