Issue
I am writing a JUnit test using MvcMock to simulate HTTP post request. However my test is continuously failing with BadRequest error. How can I make the test case PASS
Rest end point - /transaction
Request format is JSON -
{
"amount" : 12.6,
"timestamp": 1478192204001
}
Transaction.java class which I have written is -
import java.time.Instant;
public class Transaction {
private double amount;
private Instant timestamp;
public Transaction() {
}
public Transaction(double amount, Instant timestamp) {
this.amount = amount;
this.timestamp = timestamp;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public Instant getTimestamp() {
return timestamp;
}
public void setTimestamp(Instant timestamp) {
this.timestamp = timestamp;
}
@Override
public String toString() {
return super.toString();
}
}
JUnit test which I have written is below -
@RunWith(SpringRunner.class)
@WebMvcTest(controllers=TransactionController.class)
public class TransactionControllerTest {
@Autowired
private MockMvc mvc;
@MockBean
private TransactionService service;
@Test
public void shouldPostTransaction() throws JsonProcessingException, Exception {
final Transaction transaction = new Transaction(14.1, now());
when(service.add(transaction)).thenReturn(true);
ObjectMapper mapper = new ObjectMapper();
mvc.perform(
post("/transactions")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(mapper.writeValueAsString(transaction))
.accept(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isCreated())
.andExpect(content().string(""))
.andReturn();
verify(service).add(transaction);
}
}
TransactionController.java which I have written is -
@RestController
public class TransactionController {
@Autowired
private TransactionService service;
@PostMapping("/transactions")
ResponseEntity<String> add(@RequestBody Transaction transaction){
if(service.add(transaction))
return new ResponseEntity<>(CREATED);
return new ResponseEntity<>(NO_CONTENT);
}
}
Solution
The solution that worked for me is - Somehow when we use new java.time.Instant class in our code, long value of timestamp cannot directly map to Instant. Hence in the unit test using MvcMock, it always complained about BadRequest error. The issue got resolved by changing the Instant to long and then using Instant for date manipulation by converting long to Instant. Also the issue of 204 error is natural. Both the instances will be different. Hence I changed my when statement like -
when(service.add(Mockito.any(Transaction.class))).thenReturn(true);
This turned the test green
Answered By - Ashish K Agarwal