Refactor client name and add peek operation
This commit is contained in:
parent
8d4fd26273
commit
a9a896827e
10 changed files with 287 additions and 90 deletions
57
README.md
57
README.md
|
@ -68,7 +68,61 @@ Response with error message if failure:
|
||||||
<exceptionOccured>...</exceptionOccured>
|
<exceptionOccured>...</exceptionOccured>
|
||||||
```
|
```
|
||||||
|
|
||||||
## When mock was used it could be unregistered by name. It returns report of mock invocations.
|
## Mock could be peeked to get get report of its invocations.
|
||||||
|
Via client:
|
||||||
|
|
||||||
|
```
|
||||||
|
List<MockEvent> mockEvents = controlServerClient.peekMock('...')
|
||||||
|
```
|
||||||
|
|
||||||
|
Via sending POST request to localhost:<PORT>/serverControl
|
||||||
|
|
||||||
|
```
|
||||||
|
<peekMock>
|
||||||
|
<name>...</name>
|
||||||
|
</peekMock>
|
||||||
|
```
|
||||||
|
|
||||||
|
Response if success:
|
||||||
|
|
||||||
|
```
|
||||||
|
<mockPeeked>
|
||||||
|
<mockEvent>
|
||||||
|
<request>
|
||||||
|
<text>...</text>
|
||||||
|
<headers>
|
||||||
|
<param name='...'>...</param>
|
||||||
|
...
|
||||||
|
</headers>
|
||||||
|
<query>
|
||||||
|
<param name='...'>...</param>
|
||||||
|
...
|
||||||
|
</query>
|
||||||
|
<path>
|
||||||
|
<elem>...</elem>
|
||||||
|
...
|
||||||
|
</path>
|
||||||
|
</request>
|
||||||
|
<response>
|
||||||
|
<text>...</text>
|
||||||
|
<headers>
|
||||||
|
<param name='...'>...</param>
|
||||||
|
...
|
||||||
|
</headers>
|
||||||
|
<statusCode>...</statusCode>
|
||||||
|
</response>
|
||||||
|
</mockEvent>
|
||||||
|
...
|
||||||
|
</mockPeeked>
|
||||||
|
```
|
||||||
|
|
||||||
|
Response with error message if failure:
|
||||||
|
|
||||||
|
```
|
||||||
|
<exceptionOccured>...</exceptionOccured>
|
||||||
|
```
|
||||||
|
|
||||||
|
## When mock was used it could be unregistered by name. It also returns report of mock invocations.
|
||||||
Via client:
|
Via client:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -122,6 +176,7 @@ Responsewith error message if failure:
|
||||||
<exceptionOccured>...</exceptionOccured>
|
<exceptionOccured>...</exceptionOccured>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## List of current registered mocks could be retrieved:
|
## List of current registered mocks could be retrieved:
|
||||||
Via client:
|
Via client:
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package pl.touk.mockserver.client
|
||||||
|
|
||||||
|
import groovy.transform.CompileStatic
|
||||||
|
import groovy.transform.TypeChecked
|
||||||
|
|
||||||
|
@CompileStatic
|
||||||
|
@TypeChecked
|
||||||
|
class PeekMockRequestData {
|
||||||
|
String name
|
||||||
|
}
|
|
@ -9,11 +9,11 @@ import org.apache.http.entity.StringEntity
|
||||||
import org.apache.http.impl.client.CloseableHttpClient
|
import org.apache.http.impl.client.CloseableHttpClient
|
||||||
import org.apache.http.impl.client.HttpClients
|
import org.apache.http.impl.client.HttpClients
|
||||||
|
|
||||||
class ControlServerClient {
|
class RemoteMockServer {
|
||||||
private final String address
|
private final String address
|
||||||
private final CloseableHttpClient client = HttpClients.createDefault()
|
private final CloseableHttpClient client = HttpClients.createDefault()
|
||||||
|
|
||||||
ControlServerClient(String host, int port) {
|
RemoteMockServer(String host, int port) {
|
||||||
address = "http://$host:$port/serverControl"
|
address = "http://$host:$port/serverControl"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,19 @@ class ControlServerClient {
|
||||||
throw new MockDoesNotExist()
|
throw new MockDoesNotExist()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<MockEvent> peekMock(String name) {
|
||||||
|
HttpPost removeMockPost = new HttpPost(address)
|
||||||
|
removeMockPost.entity = buildPeekMockRequest(new PeekMockRequestData(name: name))
|
||||||
|
CloseableHttpResponse response = client.execute(removeMockPost)
|
||||||
|
GPathResult responseXml = Util.extractXmlResponse(response)
|
||||||
|
if (responseXml.name() == 'mockPeeked') {
|
||||||
|
return responseXml.'mockEvent'.collect {
|
||||||
|
new MockEvent(mockRequestFromXml(it.request), mockResponseFromXml(it.response))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new MockDoesNotExist()
|
||||||
|
}
|
||||||
|
|
||||||
private static MockResponse mockResponseFromXml(GPathResult xml) {
|
private static MockResponse mockResponseFromXml(GPathResult xml) {
|
||||||
return new MockResponse(xml.statusCode.text() as int, xml.text.text(), xml.headers.param.collectEntries { [(it.@name.text()):it.text()] })
|
return new MockResponse(xml.statusCode.text() as int, xml.text.text(), xml.headers.param.collectEntries { [(it.@name.text()):it.text()] })
|
||||||
}
|
}
|
||||||
|
@ -65,6 +78,14 @@ class ControlServerClient {
|
||||||
""", ContentType.create("text/xml", "UTF-8"))
|
""", ContentType.create("text/xml", "UTF-8"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static StringEntity buildPeekMockRequest(PeekMockRequestData data) {
|
||||||
|
return new StringEntity("""\
|
||||||
|
<peekMock>
|
||||||
|
<name>${data.name}</name>
|
||||||
|
</peekMock>
|
||||||
|
""", ContentType.create("text/xml", "UTF-8"))
|
||||||
|
}
|
||||||
|
|
||||||
private static StringEntity buildAddMockRequest(AddMockRequestData data) {
|
private static StringEntity buildAddMockRequest(AddMockRequestData data) {
|
||||||
return new StringEntity("""\
|
return new StringEntity("""\
|
||||||
<addMock>
|
<addMock>
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>http-mock-server</artifactId>
|
<artifactId>http-mock-server</artifactId>
|
||||||
<groupId>pl.touk.mockserver</groupId>
|
<groupId>pl.touk.mockserver</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import spock.lang.Unroll
|
||||||
|
|
||||||
class MockServerIntegrationTest extends Specification {
|
class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
ControlServerClient controlServerClient
|
RemoteMockServer remoteMockServer
|
||||||
|
|
||||||
HttpMockServer httpMockServer
|
HttpMockServer httpMockServer
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def setup() {
|
def setup() {
|
||||||
httpMockServer = new HttpMockServer(9000)
|
httpMockServer = new HttpMockServer(9000)
|
||||||
controlServerClient = new ControlServerClient('localhost', 9000)
|
remoteMockServer = new RemoteMockServer('localhost', 9000)
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() {
|
def cleanup() {
|
||||||
|
@ -33,7 +33,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add working rest mock on endpoint"() {
|
def "should add working rest mock on endpoint"() {
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -49,12 +49,12 @@ class MockServerIntegrationTest extends Specification {
|
||||||
GPathResult restPostResponse = Util.extractXmlResponse(response)
|
GPathResult restPostResponse = Util.extractXmlResponse(response)
|
||||||
restPostResponse.name() == 'goodResponseRest-request'
|
restPostResponse.name() == 'goodResponseRest-request'
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.removeMock('testRest')?.size() == 1
|
remoteMockServer.removeMock('testRest')?.size() == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
def "should add soap mock on endpoint"() {
|
def "should add soap mock on endpoint"() {
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -71,16 +71,16 @@ class MockServerIntegrationTest extends Specification {
|
||||||
soapPostResponse.name() == 'Envelope'
|
soapPostResponse.name() == 'Envelope'
|
||||||
soapPostResponse.Body.'goodResponseSoap-request'.size() == 1
|
soapPostResponse.Body.'goodResponseSoap-request'.size() == 1
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.removeMock('testSoap')?.size() == 1
|
remoteMockServer.removeMock('testSoap')?.size() == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
def "should throw exception when try to remove mock when it does not exist"() {
|
def "should throw exception when try to remove mock when it does not exist"() {
|
||||||
when:
|
when:
|
||||||
controlServerClient.removeMock('testSoap')
|
remoteMockServer.removeMock('testSoap')
|
||||||
then:
|
then:
|
||||||
thrown(MockDoesNotExist)
|
thrown(MockDoesNotExist)
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -89,16 +89,16 @@ class MockServerIntegrationTest extends Specification {
|
||||||
soap: true
|
soap: true
|
||||||
))
|
))
|
||||||
and:
|
and:
|
||||||
controlServerClient.removeMock('testSoap') == []
|
remoteMockServer.removeMock('testSoap') == []
|
||||||
when:
|
when:
|
||||||
controlServerClient.removeMock('testSoap')
|
remoteMockServer.removeMock('testSoap')
|
||||||
then:
|
then:
|
||||||
thrown(MockDoesNotExist)
|
thrown(MockDoesNotExist)
|
||||||
}
|
}
|
||||||
|
|
||||||
def "should not add mock with existing name"() {
|
def "should not add mock with existing name"() {
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -107,7 +107,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
soap: true
|
soap: true
|
||||||
))
|
))
|
||||||
when:
|
when:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint2',
|
path: 'testEndpoint2',
|
||||||
port: 9998,
|
port: 9998,
|
||||||
|
@ -121,7 +121,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should not add mock with empty name"() {
|
def "should not add mock with empty name"() {
|
||||||
when:
|
when:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: '',
|
name: '',
|
||||||
path: 'testEndpoint2',
|
path: 'testEndpoint2',
|
||||||
port: 9998,
|
port: 9998,
|
||||||
|
@ -135,7 +135,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock after deleting old mock with the same name"() {
|
def "should add mock after deleting old mock with the same name"() {
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -144,9 +144,9 @@ class MockServerIntegrationTest extends Specification {
|
||||||
soap: true
|
soap: true
|
||||||
))
|
))
|
||||||
and:
|
and:
|
||||||
controlServerClient.removeMock('testSoap') == []
|
remoteMockServer.removeMock('testSoap') == []
|
||||||
and:
|
and:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -158,14 +158,14 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add simultaneously working post and rest mocks with the same predicate and endpoint nad port"() {
|
def "should add simultaneously working post and rest mocks with the same predicate and endpoint nad port"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
predicate: '''{req -> req.xml.name() == 'request'}''',
|
predicate: '''{req -> req.xml.name() == 'request'}''',
|
||||||
response: '''{req -> "<goodResponseRest-${req.xml.name()}/>"}'''
|
response: '''{req -> "<goodResponseRest-${req.xml.name()}/>"}'''
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -193,14 +193,14 @@ class MockServerIntegrationTest extends Specification {
|
||||||
@Unroll
|
@Unroll
|
||||||
def "should dispatch rest mocks when second on #name"() {
|
def "should dispatch rest mocks when second on #name"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest1',
|
name: 'testRest1',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
predicate: '''{req -> req.xml.name() == 'request1'}''',
|
predicate: '''{req -> req.xml.name() == 'request1'}''',
|
||||||
response: '''{req -> "<goodResponseRest1/>"}'''
|
response: '''{req -> "<goodResponseRest1/>"}'''
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: secondPath,
|
path: secondPath,
|
||||||
port: secondPort,
|
port: secondPort,
|
||||||
|
@ -232,7 +232,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
@Unroll
|
@Unroll
|
||||||
def "should dispatch rest mock with response code"() {
|
def "should dispatch rest mock with response code"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest1',
|
name: 'testRest1',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -254,7 +254,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should return response code 404 and error body the same as request body when mocks does not apply"() {
|
def "should return response code 404 and error body the same as request body when mocks does not apply"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest1',
|
name: 'testRest1',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -273,7 +273,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should inform that there was problem during adding mock - invalid port"() {
|
def "should inform that there was problem during adding mock - invalid port"() {
|
||||||
when:
|
when:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint2',
|
path: 'testEndpoint2',
|
||||||
port: -1,
|
port: -1,
|
||||||
|
@ -287,13 +287,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with get method"() {
|
def "should dispatch rest mock with get method"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -310,13 +310,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with trace method"() {
|
def "should dispatch rest mock with trace method"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -333,13 +333,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with head method"() {
|
def "should dispatch rest mock with head method"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -355,13 +355,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with options method"() {
|
def "should dispatch rest mock with options method"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -377,13 +377,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with put method"() {
|
def "should dispatch rest mock with put method"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -402,13 +402,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with delete method"() {
|
def "should dispatch rest mock with delete method"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -425,13 +425,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with patch method"() {
|
def "should dispatch rest mock with patch method"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -450,7 +450,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock that return headers"() {
|
def "should add mock that return headers"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -470,7 +470,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock that accepts only when certain request headers exists"() {
|
def "should add mock that accepts only when certain request headers exists"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -499,7 +499,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock that accepts only when certain query params exists"() {
|
def "should add mock that accepts only when certain query params exists"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -523,7 +523,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock that accepts only when request has specific body"() {
|
def "should add mock that accepts only when request has specific body"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -548,7 +548,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock which response json to json"() {
|
def "should add mock which response json to json"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -573,39 +573,39 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should get list mocks"() {
|
def "should get list mocks"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9998
|
port: 9998
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest4',
|
name: 'testRest4',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999
|
port: 9999
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest3',
|
name: 'testRest3',
|
||||||
path: 'testEndpoint2',
|
path: 'testEndpoint2',
|
||||||
port: 9999
|
port: 9999
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest5',
|
name: 'testRest5',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999
|
port: 9999
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest6',
|
name: 'testRest6',
|
||||||
path: 'testEndpoint2',
|
path: 'testEndpoint2',
|
||||||
port: 9999
|
port: 9999
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999
|
port: 9999
|
||||||
))
|
))
|
||||||
controlServerClient.removeMock('testRest5')
|
remoteMockServer.removeMock('testRest5')
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.listMocks() == [
|
remoteMockServer.listMocks() == [
|
||||||
new RegisteredMock('testRest', 'testEndpoint', 9999),
|
new RegisteredMock('testRest', 'testEndpoint', 9999),
|
||||||
new RegisteredMock('testRest2', 'testEndpoint', 9998),
|
new RegisteredMock('testRest2', 'testEndpoint', 9998),
|
||||||
new RegisteredMock('testRest3', 'testEndpoint2', 9999),
|
new RegisteredMock('testRest3', 'testEndpoint2', 9999),
|
||||||
|
@ -616,7 +616,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock accepts path certain path params"() {
|
def "should add mock accepts path certain path params"() {
|
||||||
given:
|
given:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -639,7 +639,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should get mock report when deleting mock"() {
|
def "should get mock report when deleting mock"() {
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -649,7 +649,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
responseHeaders: '''{req -> ['aaa':'14']}''',
|
responseHeaders: '''{req -> ['aaa':'14']}''',
|
||||||
soap: false
|
soap: false
|
||||||
))
|
))
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -681,7 +681,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
GPathResult restPostResponse3 = Util.extractXmlResponse(response3)
|
GPathResult restPostResponse3 = Util.extractXmlResponse(response3)
|
||||||
restPostResponse3.name() == 'goodResponseRest'
|
restPostResponse3.name() == 'goodResponseRest'
|
||||||
when:
|
when:
|
||||||
List<MockEvent> mockEvents1 = controlServerClient.removeMock('testRest')
|
List<MockEvent> mockEvents1 = remoteMockServer.removeMock('testRest')
|
||||||
then:
|
then:
|
||||||
mockEvents1.size() == 2
|
mockEvents1.size() == 2
|
||||||
mockEvents1[0].request.text == '<request/>'
|
mockEvents1[0].request.text == '<request/>'
|
||||||
|
@ -700,7 +700,82 @@ class MockServerIntegrationTest extends Specification {
|
||||||
mockEvents1[1].response.text == '<goodResponseRest-request15/>'
|
mockEvents1[1].response.text == '<goodResponseRest-request15/>'
|
||||||
mockEvents1[1].response.statusCode == 201
|
mockEvents1[1].response.statusCode == 201
|
||||||
when:
|
when:
|
||||||
List<MockEvent> mockEvents2 = controlServerClient.removeMock('testRest2')
|
List<MockEvent> mockEvents2 = remoteMockServer.removeMock('testRest2')
|
||||||
|
then:
|
||||||
|
mockEvents2.size() == 1
|
||||||
|
mockEvents2[0].request.text == '<reqXYZ/>'
|
||||||
|
!mockEvents2[0].request.headers?.keySet()?.empty
|
||||||
|
mockEvents2[0].request.query == [id: '123']
|
||||||
|
mockEvents2[0].request.path == ['testEndpoint']
|
||||||
|
mockEvents2[0].response.headers.aaa == '15'
|
||||||
|
mockEvents2[0].response.text == '<goodResponseRest/>'
|
||||||
|
mockEvents2[0].response.statusCode == 202
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should get mock report when peeking mock"() {
|
||||||
|
expect:
|
||||||
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
|
name: 'testRest',
|
||||||
|
path: 'testEndpoint',
|
||||||
|
port: 9999,
|
||||||
|
predicate: '''{req -> req.xml.name()[0..6] == 'request' }''',
|
||||||
|
response: '''{req -> "<goodResponseRest-${req.xml.name()}/>"}''',
|
||||||
|
statusCode: 201,
|
||||||
|
responseHeaders: '''{req -> ['aaa':'14']}''',
|
||||||
|
soap: false
|
||||||
|
))
|
||||||
|
remoteMockServer.addMock(new AddMockRequestData(
|
||||||
|
name: 'testRest2',
|
||||||
|
path: 'testEndpoint',
|
||||||
|
port: 9999,
|
||||||
|
predicate: '''{req -> req.xml.name() == 'reqXYZ' }''',
|
||||||
|
response: '''{req -> "<goodResponseRest/>"}''',
|
||||||
|
statusCode: 202,
|
||||||
|
responseHeaders: '''{req -> ['aaa':'15']}''',
|
||||||
|
soap: false
|
||||||
|
))
|
||||||
|
when:
|
||||||
|
HttpPost post1 = new HttpPost('http://localhost:9999/testEndpoint')
|
||||||
|
post1.entity = new StringEntity('<request/>', ContentType.create("text/xml", "UTF-8"))
|
||||||
|
CloseableHttpResponse response1 = client.execute(post1)
|
||||||
|
then:
|
||||||
|
GPathResult restPostResponse1 = Util.extractXmlResponse(response1)
|
||||||
|
restPostResponse1.name() == 'goodResponseRest-request'
|
||||||
|
when:
|
||||||
|
HttpPost post2 = new HttpPost('http://localhost:9999/testEndpoint/hello')
|
||||||
|
post2.entity = new StringEntity('<request15/>', ContentType.create("text/xml", "UTF-8"))
|
||||||
|
CloseableHttpResponse response2 = client.execute(post2)
|
||||||
|
then:
|
||||||
|
GPathResult restPostResponse2 = Util.extractXmlResponse(response2)
|
||||||
|
restPostResponse2.name() == 'goodResponseRest-request15'
|
||||||
|
when:
|
||||||
|
HttpPost post3 = new HttpPost('http://localhost:9999/testEndpoint?id=123')
|
||||||
|
post3.entity = new StringEntity('<reqXYZ/>', ContentType.create("text/xml", "UTF-8"))
|
||||||
|
CloseableHttpResponse response3 = client.execute(post3)
|
||||||
|
then:
|
||||||
|
GPathResult restPostResponse3 = Util.extractXmlResponse(response3)
|
||||||
|
restPostResponse3.name() == 'goodResponseRest'
|
||||||
|
when:
|
||||||
|
List<MockEvent> mockEvents1 = remoteMockServer.peekMock('testRest')
|
||||||
|
then:
|
||||||
|
mockEvents1.size() == 2
|
||||||
|
mockEvents1[0].request.text == '<request/>'
|
||||||
|
!mockEvents1[0].request.headers?.keySet()?.empty
|
||||||
|
mockEvents1[0].request.query == [:]
|
||||||
|
mockEvents1[0].request.path == ['testEndpoint']
|
||||||
|
!mockEvents1[0].response.headers?.keySet()?.empty
|
||||||
|
mockEvents1[0].response.text == '<goodResponseRest-request/>'
|
||||||
|
mockEvents1[0].response.statusCode == 201
|
||||||
|
|
||||||
|
mockEvents1[1].request.text == '<request15/>'
|
||||||
|
!mockEvents1[1].request.headers?.keySet()?.empty
|
||||||
|
mockEvents1[1].request.query == [:]
|
||||||
|
mockEvents1[1].request.path == ['testEndpoint', 'hello']
|
||||||
|
!mockEvents1[1].response.headers?.keySet()?.empty
|
||||||
|
mockEvents1[1].response.text == '<goodResponseRest-request15/>'
|
||||||
|
mockEvents1[1].response.statusCode == 201
|
||||||
|
when:
|
||||||
|
List<MockEvent> mockEvents2 = remoteMockServer.peekMock('testRest2')
|
||||||
then:
|
then:
|
||||||
mockEvents2.size() == 1
|
mockEvents2.size() == 1
|
||||||
mockEvents2[0].request.text == '<reqXYZ/>'
|
mockEvents2[0].request.text == '<reqXYZ/>'
|
||||||
|
|
|
@ -8,7 +8,7 @@ import org.apache.http.entity.ContentType
|
||||||
import org.apache.http.entity.StringEntity
|
import org.apache.http.entity.StringEntity
|
||||||
import org.apache.http.impl.client.HttpClients
|
import org.apache.http.impl.client.HttpClients
|
||||||
import pl.touk.mockserver.client.AddMockRequestData
|
import pl.touk.mockserver.client.AddMockRequestData
|
||||||
import pl.touk.mockserver.client.ControlServerClient
|
import pl.touk.mockserver.client.RemoteMockServer
|
||||||
import pl.touk.mockserver.client.Util
|
import pl.touk.mockserver.client.Util
|
||||||
import pl.touk.mockserver.server.HttpMockServer
|
import pl.touk.mockserver.server.HttpMockServer
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
|
@ -18,7 +18,7 @@ class ServerMockPT extends Specification {
|
||||||
def "should handle many request simultaneously"() {
|
def "should handle many request simultaneously"() {
|
||||||
given:
|
given:
|
||||||
HttpMockServer httpMockServer = new HttpMockServer()
|
HttpMockServer httpMockServer = new HttpMockServer()
|
||||||
ControlServerClient controlServerClient = new ControlServerClient("localhost", 9999)
|
RemoteMockServer controlServerClient = new RemoteMockServer("localhost", 9999)
|
||||||
HttpClient client = HttpClients.createDefault()
|
HttpClient client = HttpClients.createDefault()
|
||||||
int requestAmount = 1000
|
int requestAmount = 1000
|
||||||
GPathResult[] responses = new GPathResult[requestAmount]
|
GPathResult[] responses = new GPathResult[requestAmount]
|
||||||
|
|
|
@ -60,6 +60,14 @@ class ContextExecutor {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<MockEvent> peekMock(String name) {
|
||||||
|
Mock mock = mocks.find { it.name == name }
|
||||||
|
if (mock) {
|
||||||
|
return mock.history
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
void addMock(Mock mock) {
|
void addMock(Mock mock) {
|
||||||
mocks << mock
|
mocks << mock
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ class HttpMockServer {
|
||||||
addMock(request, ex)
|
addMock(request, ex)
|
||||||
} else if (request.name() == 'removeMock') {
|
} else if (request.name() == 'removeMock') {
|
||||||
removeMock(request, ex)
|
removeMock(request, ex)
|
||||||
|
} else if (request.name() == 'peekMock') {
|
||||||
|
peekMock(request, ex)
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException('Unknown request')
|
throw new RuntimeException('Unknown request')
|
||||||
}
|
}
|
||||||
|
@ -109,45 +111,67 @@ class HttpMockServer {
|
||||||
createResponse(ex, createMockRemovedResponse(mockEvents), 200)
|
createResponse(ex, createMockRemovedResponse(mockEvents), 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void peekMock(GPathResult request, HttpExchange ex) {
|
||||||
|
String name = request.name
|
||||||
|
if (!(name in mockNames)) {
|
||||||
|
throw new RuntimeException('mock not registered')
|
||||||
|
}
|
||||||
|
log.info("Peeking mock $name")
|
||||||
|
List<MockEvent> mockEvents = childServers.collect { it.peekMock(name) }.flatten()
|
||||||
|
createResponse(ex, createMockPeekedResponse(mockEvents), 200)
|
||||||
|
}
|
||||||
|
|
||||||
private static String createMockRemovedResponse(List<MockEvent> mockEvents) {
|
private static String createMockRemovedResponse(List<MockEvent> mockEvents) {
|
||||||
StringWriter sw = new StringWriter()
|
StringWriter sw = new StringWriter()
|
||||||
MarkupBuilder builder = new MarkupBuilder(sw)
|
MarkupBuilder builder = new MarkupBuilder(sw)
|
||||||
builder.mockRemoved {
|
builder.mockRemoved {
|
||||||
mockEvents.each { MockEvent m ->
|
mockEventsToXml(mockEvents, builder)
|
||||||
|
}
|
||||||
|
return sw.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String createMockPeekedResponse(List<MockEvent> mockEvents) {
|
||||||
|
StringWriter sw = new StringWriter()
|
||||||
|
MarkupBuilder builder = new MarkupBuilder(sw)
|
||||||
|
builder.mockPeeked {
|
||||||
|
mockEventsToXml(mockEvents, builder)
|
||||||
|
}
|
||||||
|
return sw.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void mockEventsToXml(List<MockEvent> events, MarkupBuilder builder) {
|
||||||
|
events.each { MockEvent event ->
|
||||||
builder.mockEvent {
|
builder.mockEvent {
|
||||||
builder.request {
|
builder.request {
|
||||||
text m.request.text
|
text event.request.text
|
||||||
headers {
|
headers {
|
||||||
m.request.headers.each {
|
event.request.headers.each {
|
||||||
builder.param(name: it.key, it.value)
|
builder.param(name: it.key, it.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
query {
|
query {
|
||||||
m.request.query.each {
|
event.request.query.each {
|
||||||
builder.param(name: it.key, it.value)
|
builder.param(name: it.key, it.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
path {
|
path {
|
||||||
m.request.path.each {
|
event.request.path.each {
|
||||||
builder.elem it
|
builder.elem it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
builder.response {
|
builder.response {
|
||||||
text m.response.text
|
text event.response.text
|
||||||
headers {
|
headers {
|
||||||
m.response.headers.each {
|
event.response.headers.each {
|
||||||
builder.param(name: it.key, it.value)
|
builder.param(name: it.key, it.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statusCode m.response.statusCode
|
statusCode event.response.statusCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String string = sw.toString()
|
|
||||||
return string
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void createErrorResponse(HttpExchange ex, Exception e) {
|
private static void createErrorResponse(HttpExchange ex, Exception e) {
|
||||||
StringWriter sw = new StringWriter()
|
StringWriter sw = new StringWriter()
|
||||||
|
|
|
@ -48,6 +48,10 @@ class HttpServerWraper {
|
||||||
return executors.collect { it.removeMock(name) }.flatten()
|
return executors.collect { it.removeMock(name) }.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<MockEvent> peekMock(String name) {
|
||||||
|
return executors.collect { it.peekMock(name) }.flatten()
|
||||||
|
}
|
||||||
|
|
||||||
List<Mock> getMocks() {
|
List<Mock> getMocks() {
|
||||||
return executors.collect { it.mocks }.flatten()
|
return executors.collect { it.mocks }.flatten()
|
||||||
}
|
}
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -9,7 +9,7 @@
|
||||||
<modules>
|
<modules>
|
||||||
<module>mockserver-client</module>
|
<module>mockserver-client</module>
|
||||||
<module>mockserver</module>
|
<module>mockserver</module>
|
||||||
<!--<module>mockserver-tests</module>-->
|
<module>mockserver-tests</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue