I have implemented a basic WireMock with a sample REST/HTTP request simulation. The server code implemented as below.
With this code, I get the following error when I issue the GET request from Postman (i.e. GET http://127.0.0.1:8089/some/thing).
No response could be served as there are no stub mappings in this WireMock instance.
What is missing in my setup/code?
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
public class MockApp {
private WireMockServer wireMockServer;
public MockApp(String testSpec) {
wireMockServer = new WireMockServer(WireMockConfiguration.options().
port(8089).
usingFilesUnderDirectory(testSpec).
disableRequestJournal());
}
public void start() {
wireMockServer.start();
}
public void stop() {
wireMockServer.stop();
}
}
The main function is:
public class MockMain {
public static void main(String[] args) {
String baseDir = System.getProperty("user.dir");
String testResource = baseDir + "/resources/testconfig/";
MockAMS mockAMS = new MockAMS(testResource);
mockAMS.start();
}
}
Under 'resources/testconfig', there is a file called mapping.json containing:
{
"request": {
"method": "GET",
"url": "/some/thing"
},
"response": {
"status": 200,
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
}
}
}
I found solution for this. So, basically we need create a folder called "mappings" (exact name) under the directory identified by "testResource" variable. So in above code example, the mapping.json file will be stored at location: "MockApp/resources/testconfig/mappings/mapping.json".
Once this, is done, it will print the following output. As can be seen in the logs, "Stub mapping size is 1". This will be printed once you add the following line in the code.
System.out.println("Stub mapping size: " + wireMockServer.getStubMappings().size());
Stub mapping size: 1
{
"id" : "da5735a6-b6cc-45aa-8256-fb88b5670610",
"request" : {
"url" : "/some/thing",
"method" : "GET"
},
"response" : {
"status" : 200,
"body" : "Hello world!",
"headers" : {
"Content-Type" : "text/plain"
}
},
"uuid" : "da5735a6-b6cc-45aa-8256-fb88b5670610"
}
Related
I am using
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<version>5.11.2</version>
<scope>test</scope>
</dependency>
for integration tests of a REST API. I've started with very basic expectations, to further ellaborate the tests later, once the minimum stuff passes the test. To my surpise, MockServer keeps telling me that no received requests match my expectations.
I am using the Java API, to write tests that use Mockito and PowerMock to deal with static methods. TestNG is the Test Freamework.
This is my code:
#PowerMockIgnore({"javax.xml.parsers.*", "org.apache.logging.log4j.*", "com.sun.org.apache.*", "sun.security.*", "javax.net.ssl.*"})
#PrepareForTest({K8sTarget.class, K8sApi.class})
public class DataAccessImplTest extends PowerMockTestCase {
private static final String HTTP_METHOD_GET = "GET";
private static final String USER_ID= "46756123123";
private static final String USERS_PATH = "/api/v1/users/%s";
private static final String CONTENT_TYPE_APP_JSON = "application/json";
#Mock
Target mockTarget;
#Mock
K8sClient mockK8sClient;
private DataAccessFactory dataAccessFactory;
private DataAccessImpl dataAccessUT;
private MockServerClient mockServer;
AutoCloseable closeable;
#BeforeClass
public void setup() {
// ensure all connection using HTTPS will use the SSL context defined by
// MockServer to allow dynamically generated certificates to be accepted
HttpsURLConnection.setDefaultSSLSocketFactory(
new KeyStoreFactory(new MockServerLogger()).sslContext().getSocketFactory());
this.mockServer = startClientAndServer(PortFactory.findFreePort());
this.closeable = MockitoAnnotations.openMocks(this);
dataAccessFactory = DataAccessFactory.getInstance();
assertNotNull(dataAccessFactory);
PowerMockito.mockStatic(K8sApi.class);
PowerMockito.mockStatic(K8sTarget.class);
PowerMockito.when(K8sApi.getK8sClient()).thenReturn(mockK8sClient);
PowerMockito.when(K8sTarget.of(Mockito.any(K8sClient.class), Mockito.any(Target.class))).thenReturn(mockTarget);
Mockito.when(mockTarget.getName()).thenReturn("localhost");
Mockito.when(mockTarget.getPort()).thenReturn(this.mockServer.getPort().intValue());
dataAccessUT = dataAccessFactory.createDataClient();
}
#BeforeMethod
public void prepareMocks() {
Mockito.when(mockTarget.getName()).thenReturn("localhost");
Mockito.when(mockTarget.getPort()).thenReturn(this.mockServer.getPort().intValue());
}
#AfterClass
public void teardown() throws Exception {
this.closeable.close();
this.mockServer.stop();
}
#Test
public void getUserTest_200_Ok() throws IOException {
dataAccessUT.getUserData(USER_ID);
mockServer.when(request()
.withMethod(HTTP_METHOD_GET)
.withPath(String.format(USERS_PATH, USER_ID))
)
.respond(
response()
.withStatusCode(HttpStatusCode.OK_200.code())
.withHeader(HttpHeaderNames.CONTENT_TYPE.toString(), CONTENT_TYPE_APP_JSON)
.withBody("some_response_body")
);
}
}
and these are the console logs:
10:06:24.067 [nioEventLoopGroup-2-1] DEBUG com.commonlibrary.httpclient.common.HttpConnectionListener:28 - 0.1 HttpConnectionListener::operationComplete: connected to [localhost:58136] from [/127.0.0.1:58204]
10:06:24.285 [MockServer-EventLog0] INFO org.mockserver.log.MockServerEventLog:108 - 58136 received request:
{
"method" : "GET",
"path" : "/api/v1/users/46756123123",
"headers" : {
"authorization" : [ "Bearer token" ],
"accept" : [ "application/json" ],
"host" : [ "localhost:58136" ],
"content-length" : [ "0" ]
},
"keepAlive" : true,
"secure" : false
}
10:06:24.350 [MockServer-EventLog0] INFO org.mockserver.log.MockServerEventLog:108 - 58136 no expectation for:
{
"method" : "GET",
"path" : "/api/v1/users/46756123123",
"headers" : {
"authorization" : [ "Bearer token" ],
"accept" : [ "application/json" ],
"host" : [ "localhost:58136" ],
"content-length" : [ "0" ]
},
"keepAlive" : true,
"secure" : false
}
returning response:
{
"statusCode" : 404,
"reasonPhrase" : "Not Found"
}
10:06:24.483 [MockServer-EventLog0] INFO org.mockserver.log.MockServerEventLog:108 - 58136 stopped for port: 58136
As you can see (unless I am missing something) request should match the expectation, but it doesn'. I have tried several things, all of them without success:
reduce the request expectation to the bare minimum, just calling request() without defining anything else. This shouls match EVERY incoming request. Same result.
introduce Times.exactly(1) in the expectation. Same result.
specify the headers I am sending in the request, even though my understanding is that if they are not set in the expectation, they are not used for matching. Same result.
After 2 days, I am running out of ideas, so any help or hint would be appreciated. Thanks!
Edition after following hint and checking code examples in MockServer site
Following #peter-rowth suggestion, I moved the request sent after creating expectations and it worked.
I am editing this issue also to make clear that it duplicates [https://stackoverflow.com/questions/63843619/mockserver-request-not-found][1], that I found later.
It looks like in your test you are creating the expectations in MockServer after executing the call to your code under test? The fact that your console output from MockServer does not output matched/not matched expectations (the default behavior) indicated to me that there are no expectations setup when the web request is made to MockServer and a 404 is default response by MockServer when there is no expectation for a request.
Try adding that expectation as the first line in your test.
This is my sample Json Data coming from .json file now I want to do bulk_insert to elasticsearch dynamically so that I can perform operations on it ..can someone help me with java code to add this data dynamically ..this is just a piece of 5-6objects like this i have more then 500objects
[{
"data1" : "developer",
"data2" : "categorypos",
"data3" : "1001"
},
{
"data1" : "developer",
"data1" : "developerpos",
"data1" : "1002"
},
{
"data1" : "developer",
"data2" : "developpos",
"data3" : "1003"
},
{
"data1" : "support",
"data2" : "datapos",
"data3" : "1004"
}
]
There is a provision of bulk operations in elastic search following is the documentation this might help
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
You need to read the file from your application, iterate over the array and for each document, send it to elasticsearch.
To do the latest, you should use the bulk processor class.
BulkProcessor bulkProcessor = BulkProcessor.builder(
(request, bulkListener) -> esClient.bulkAsync(request, RequestOptions.DEFAULT, bulkListener),
new BulkProcessor.Listener() {
#Override
public void beforeBulk(long executionId, BulkRequest request) { }
#Override
public void afterBulk(long executionId, BulkRequest request, BulkResponse response) { }
#Override
public void afterBulk(long executionId, BulkRequest request, Throwable failure) { }
})
.setBulkActions(10000)
.setFlushInterval(TimeValue.timeValueSeconds(5))
.build();
For each json document, call:
bulkProcessor.add(new IndexRequest("INDEXNAME").source(json, XContentType.JSON));
My wiremock doesn't seem to work with autoconfigure. I have json files in a folder named stubs in the classpath and I ran the standalone jar on the port 8080.
#AutoConfigureWireMock(stubs="classpath:/stubs", port = 0)
public class TestResource {
#Autowired
private Service service;
#Test
public void contextLoads() throws Exception {
assertThat(this.service.go()).isEqualTo("Hello World!");
}
}
Example of a json file
{
"request" : {
"url" : "/api/users",
"method" : "GET",
"bodyPatterns" : [ {
"contains" : "some soap body"
}]
},
"response" : {
"status" : 200,
"body" : "Hello World",
"headers" : {
"X-Application-Context" : "application:-1",
"Content-Type" : "text/plain"
}
}
}
When I launch a request with GET -> localhost:8080/api/users/ It doesn't match with the json file.
Thanks in advance
I simply added all my json with a POST request on localhost:8080/__admin/mappings/import
http://wiremock.org/docs/stubbing/
With the following setup, spring doesn't pick a transformer defined in JSON file which is under mappings directory, but it does when I declare it directly in test code.
#Configuration
public class WiremockConfiguration {
#Bean
WireMockConfigurationCustomizer optionsCustomizer() {
return new WireMockConfigurationCustomizer() {
#Override
public void customize(WireMockConfiguration options) {
options.extensions(BodyDefinitionTransformer.class);
}
};
}
}
{
"request": {
"method": "POST",
"urlPattern": "/some/thing"
},
"response": {
"status": 200,
"bodyFileName": "my_payload.json",
"transformers": [
"body-transformer"
],
"headers": {
"Content-Type": "application/json"
}
}
}
public class BodyDefinitionTransformer extends ResponseDefinitionTransformer {
#Override
public ResponseDefinition transform(Request request, ResponseDefinition responseDefinition, FileSource files,
Parameters parameters) {
return responseDefinition; //checking if this work by putting breakpoint here
}
#Override
public boolean applyGlobally() {
return false;
}
#Override
public String getName() {
return "body-transformer";
}
}
#ContextConfiguration
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#TestPropertySource
#AutoConfigureWireMock(port = 9632)
class DummyTestClass extends Specification {
def "some dummy test" () {
when:
stubFor(post("/some/thing").willReturn(aResponse()
//.withTransformers("body-transformer") transformer work if I declare it in this way
.withTransformerParameter("test", "test"
)))
// rest of my test where execute above request
}
}
The code works perfectly when I declare it using .withTransformers("body-transformer") but when I put transformer name into transformers array in JSON file, it doesn't work. Do you have any ideas why?
I have designed login module in RESTFul API using jersey.
whenever any error occurred while login it will return error code and message like,
{
"errorFlag": 1,
"errorMessage": "Login Failed"
}
but whenever I get successful results it returns
{
"apiKey": "3942328b-fa65-496c-bf32-910aafbc1b0e",
"email": "caXXXX#gmail.inl",
"name": "Chandrakant"
}
I'm looking for results like below
{
"errorFlag": 0,
"errorMessage":{
"apiKey": "3942328b-fa65-496c-bf32-910aafbc1b0e",
"email": "caXXXX#gmail.inl",
"name": "Chandrakant"}
}
Use structure like below,
{
status/statusCode : 200/400, //eg. 200 for success, any other for failure.
statusMessage : "Success/<failureMessage>",
errorDetails : "Failed due to <reason>" //optional
data :{ //data will exists only in case of success call.
}
}
you can achieve this like below,
#GET
#Path("/images/{image}")
#Produces("image/*")
public Response getImage(#PathParam("image") String image) {
File f = new File(image);
if (!f.exists()) {
throw new WebApplicationException(404);
}
String mt = new MimetypesFileTypeMap().getContentType(f);
return Response.ok(f, mt).build();
}
You can return all the attributes in HashMap as key value .
Below piece of code worked for me
#POST
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public HashMap check(InputStream inputJsonObj) {
HashMap map = new HashMap();
map.put("key1", "value1");
return map;
}