Wiremock mock returning HTTP 500 - junit4

I am using wireMock and I am getting a consistent response of 500 Internal Server Error even though the stubbed response is 200 OK.
If I debug, I see the connection is always closed. Any idea what might be going wrong? Or what I am doing wrong.
Here's the test
public class MyControllerTest {
#Autowired
MyController myController;
String id1 = "id1";
String id2 = "id2";
Integer offset = 0;
Integer limit = 1;
int port = 8080;
protected WireMockServer wireMockServer;
#Rule
public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port(port);
#Test
public void hosDriversHoursOfServiceGet() throws Exception {
stubFor(WireMock.get(urlEqualTo("/path/endPoint"))
.withQueryParam("id1", equalTo(id1))
.withQueryParam("id2", equalTo(id2))
.withQueryParam("limit", equalTo(limit.toString()))
.withQueryParam("offset", equalTo(offset.toString()))
.willReturn(aResponse().withStatus(200).withBody((getJsonString()))));
Response response = myController.hosDriversHoursOfServiceGet(driverId, 1, 1);
assertEquals(Integer.valueOf(1), response.getCount());
}
private String getJsonString() {
return "{\"count\":1}";
}
}
Trying to mock:
http://localhost:8080/path/endPoint?id1={id1}&id2={id2}&limit={limit}&offset={offset}
The above call is made in a client class which is autowired in MyController. Is that even possible to mock since it's not a direct call?

The issue is resolved, it's all related to Javax-servlet-api dependency in wiremock and my application. Changed the wiremock from wiremock 2.6.0 to wiremock-standalone, which used application's servlet-api dependency, essentially it worked.
Not sure if this is the right answer, but it worked.

Related

SpringBoot Test Cases not working in the way they were expected to

I have been working on a basic Spring Boot Application building REST APIs. I have learnt to write the APIs and now I am trying to write Unit Tests for them. I have written one unit test for the get API and one for the post API. The post API test seems to be running fine but the get api test fails. I am not sure why. I am not sure if the get test is running before the post and hence nothing is available so it fails?
I have tried changing the order in which the tests are written in order to see the execution order changes but it hasn't changed.
#RunWith(SpringRunner.class)
#WebMvcTest(value = ProjectRestController.class)
public class ProjectControllerTest
{
private String baseURL = "http://localhost:8080/";
private String expectedResult = "{id:0, name:\"Testing Course 0\", description: \"This is a test for course 0\"}";
#Autowired
private MockMvc mockMvc;
#MockBean
private ProjectService projectService;
Project mockProject = new Project(0, "Testing Course 0", "This is a test for course 0");
#Test
public void addProject() throws Exception
{
mockMvc.perform(MockMvcRequestBuilders.post(baseURL+"/projects")
.content(asJsonString(new Project(0, "Test 0", "Testing Project 0")))
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
//This test does not seem to work. Returns 404
#Test
public void getProject() throws Exception
{
mockMvc.perform(MockMvcRequestBuilders.get(baseURL+"/projects/0")
.accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
}
public static String asJsonString(final Object obj)
{
try
{
return new ObjectMapper().writeValueAsString(obj);
} catch (Exception e)
{
throw new RuntimeException(e);
}
}
}
I expected a status 200 from the GET as the post is working fine however the get returns a 404.
The issue is due to you have a base URL you should not send the base URL, pass only /project/0

How to write integration tests for spring-batch-integration?

I'm using spring-integration bundled with spring-batch and got stuck trying to write integration tests to test the whole flow, not just single config.
I've created Embedded Sftp Server for this tests and trying to send message to sftpInboundChannel - the message is sent, but nothing happens, but when i send this message to the next channel (after sftpInboundChannel) it goes ok. Also i'm not able to load test source properties, even though i'm using #TestPropertySource annotation.
This are my class annotations
#TestPropertySource(properties = {
//here goes all the properties
})
#EnableConfigurationProperties
#RunWith(SpringRunner.class)
#Import({TestConfig.class, SessionConfig.class})
#ActiveProfiles("it")
#SpringIntegrationTest
#EnableIntegration
#SpringBootTest
#DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
This is my class body
#Autowired
private PollableChannel sftpInboundChannel;
#Autowired
private SessionFactory<ChannelSftp.LsEntry> defaultSftpSessionFactory;
#Autowired
private EmbeddedSftpServer server;
#Test
public void shouldDoSmth() {
RemoteFileTemplate<ChannelSftp.LsEntry> template;
try {
template = new RemoteFileTemplate<>(defaultSftpSessionFactory);
SftpTestUtils.moveToRemoteFolder(template);
final List<ChannelSftp.LsEntry> movedFiles = SftpTestUtils.listFilesFromDirectory("folder/subfolder", template);
log.info("Moved file {}", movedFiles.size());
final MessageBuilder<String> messageBuilder = MessageBuilder.withPayload("Sample.txt") // path to file
.setHeader("file_Path", "Sample.txt")
boolean wasSent = this.sftpInboundChannel.send(messageBuilder.build());
log.info("Was sent to sftpInboundChannel channel {}", wasSent);
log.info("message {}", messageBuilder.build());
} finally {
SftpTestUtils.cleanUp();
}
}
To the case of not read the property file one solution is add in your Test class something like this:
#BeforeClass
public static void beforeClass() {
System.setProperty("propertyfile", "nameOfFile.properties");
}
A second way is to create a xml (or class) config where you add the tag:
<context:property-placeholder
location="nameOfFile.properties"
ignore-resource-not-found="true" system-properties-mode="OVERRIDE" />
and your file will be localized.
The property file should be inside of resources folder.

Error resolving template - url mapping fails

I receive the following error message:
Error resolving template [catalog/getCatalogItemFromCatalog/catalogItemId/3916677], template might not exist or might not be accessible by any of the configured Template Resolvers
I am trying to reach my service and the method using this url:
http://192.168.99.100:31003/catalog/getCatalogItemFromCatalog/catalogItemId/3916677
Controller:
#Controller
#RequestMapping("catalog")
public class CatalogController {
#GetMapping("/getCatalogItemFromCatalog/catalogItemId/{catalogItemId}")
public CatalogItem getCatalogItemFromCatalog(#PathVariable Integer catalogItemId){
List<Catalog> catalogs = getAllCatalogs();
Optional<CatalogItem> optionalCatalogItem = Optional.empty();
for(Catalog catalog : catalogs){
optionalCatalogItem = catalog.getCatalogItems().stream().filter(it -> it.getCatalogItemId().equals(catalogItemId)).findFirst();
}
return optionalCatalogItem.orElse(null);
}
#GetMapping("/system/ipaddr")
public String getIpAddr() {
List<String> response;
response = runSystemCommandAndGetResponse(IP_ADDR);
return new Gson().toJson(response);
}
}
When I curl
http://192.168.99.100:31003/catalog/system/ipaddr
I have no issues.
I am testing for hours now and nothing seems to work, I have no idea why its failing tho.
you have #Controller on your class which means spring will try to resolve the return type of all your methods inside the controller using all the available templateResolvers.
by using #ResponseBody spring will wrap the return type inside the response (after converting it) directly then returns it to the client, it's similar to using #RestController instead #Controller

Spring boot restful service Post request always returns null as response message in test code using Junit

This is a demo controller.
#PostMapping("/rest/new")
public ResponseEntity<MessageDto> newUser(#RequestBody UserDto userDto) {
return ResponseEntity.ok(new MessageDto().setMessage(userService.createUser(userDto)));
}
This is service layer.
#Override
public String createUser(UserDto userDto) {
// Do Something
return "Successful!!";
}
This is the test code to test the controller
#Test
public void testPostRestController() throws Exception {
UserDto userDto = new UserDto();
userDto.setName("AA");
userDto.setEmail("a#a.a");
userDto.setId((long) 1);
when(userService.createUser(userDto)).thenReturn("Successful!!");
mockMvc.perform(post("/rest/new")
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.content(new ObjectMapper().writeValueAsString(userDto)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$.message", is(userService.createUser(userDto))))
.andDo(MockMvcResultHandlers.print());
}
The problem is when I run the test code, it is supposed to check the response status and response message. The response status matched but the problem is the response message always returns as null.
error:
java.lang.AssertionError: JSON path "$.message"
Expected: is "Successful!!"
but: was null
Am I missing something here?
Try using
when(userService.createUser(any(UserDto.class))).thenReturn("Successful!!");
Instead of
when(userService.createUser(userDto)).thenReturn("Successful!!");
This should ideally fix the NPE

extracting the complete envelope xml from MessageContext

I have an interceptor like this:
public class WebServiceInterceptor extends EndpointInterceptorAdapter {
#Inject
private Jaxb2Marshaller myJaxb2Marshaller;
#Inject
private WebServiceHistoryDao webServiceHistoryDao;
#Override
public boolean handleRequest(MessageContext messageContext, Object endpoint)
throws Exception {
Source payloadSource = messageContext.getRequest().getPayloadSource();
Object unmarshaled = myJaxb2Marshaller.unmarshal(payloadSource);
//EXTRACT XML HERE
//is there a better way than this:
String extractedXml = myJaxb2Marshaller.marshal(unmarshaled);
return true;
}
}
How can i extract the whole xml of envelope (for logging purposes - to write it to the DB)
You don't need to write one, there's an existing one in the API - SoapEnvelopeLoggingInterceptor. See the javadoc.
SOAP-specific EndpointInterceptor that logs the complete request and response envelope of SoapMessage messages. By default, request, response and fault messages are logged, but this behaviour can be changed using the logRequest, logResponse, logFault properties.
If you only need to see the payload, rather than the entire SOAP envelope, then there's PayloadLoggingInterceptor.