I am building unit tests in a Spring Boot Java application for a service class.
The service class makes an external call to a REST API service that return a JSON response. I am mocking this call using Mockito. I am hardcoding a JSON in the mockserver response.
Is this bad practice to have hardcoded JSONs in your unit tests? If the JSON structure changes, then the test should fail is my reasoning. Is there a better, best practice where to do this?
Example Snippet below:
The actual code is functional, I just edited this snippet it for brevity to get the idea across, so post a comment if you see any errors:
public class UserServiceTest extends TestCase {
private static final String MOCK_URL = "baseUrl";
private static final String DEFAULT_USER_ID = "353";
UserService classUnderTest;
ResponseEntity<Customer> mockResponseEntity;
MockRestServiceServer mockServer;
@Mock
RestTemplate mockRestTemplate;
public void setUp() throws Exception {
super.setUp();
classUnderTest = new UserRestService();
mockRestTemplate = new RestTemplate();
mockServer = MockRestServiceServer.createServer(mockRestTemplate);
ReflectionTestUtils.setField(classUnderTest, "restTemplate",
mockRestTemplate);
ReflectionTestUtils.setField(classUnderTest, "userSvcUrl",
MOCK_URL);
}
public void testGetUserById() throws Exception {
mockServer.expect(requestTo(MOCK_URL + "/Users/" + DEFAULT_USER_ID)).andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(
"{\n" +
" \"UserCredentials\": {\n" +
" \"Password\": \"\",\n" +
" \"PasswordNeedsUpdate\": false,\n" +
" \"Security\": [\n" +
" {\n" +
" \"Answer\": \"\",\n" +
" \"Question\": \"Why did the bicycle fall over?\"\n" +
" }\n" +
" ]\n" +
"}"
, MediaType.APPLICATION_JSON));
Customer customer = classUnderTest.getUserById(DEFAULT_USER_ID);
mockServer.verify();
assertNotNull(customer);
assertEquals(DEFAULT_USER_ID, customer.getId());
}
}
Mockito is a mocking framework, JAVA-based library that is used for effective unit testing of JAVA applications. Mockito is used to mock interfaces so that a dummy functionality can be added to a mock interface that can be used in unit testing.
Unit tests are just one of many software testing methods for testing your REST APIs. They should be used wherever it is appropriate.
JUnit is a framework that helps with writing and running your unit tests. Mockito (or any other mocking tool) is a framework that you specifically use to efficiently write certain kind of tests.
I am currently in the same boat as you and my reasoning was as follows:
Creating a dummy JSON-response is like mocking an object and controlling it using Mockito.when
. You would need to change anything in the when().thenReturn()
call when you changed some inner parsing or you expect different results. This is the same with a JSON-response where calls are changed and object representations are altered.
Therefore my guess would be that this is fine. Reading various articles about testing REST API's, the general concensus is that creating dummy JSON-responses is good practice. Best practice would be to (from time to time) download the real JSON-response and insert this as the mocked response. This way you can keep your tests up-to-date with the external party, while the tests can run without internet requests.
Edit as requested:
Ruby - Stubbing external services,
Python - Testing a successful call
JavaScript - An example of AJAX testing
Python - Lastly a Google tutorial about mocking
I would like to shine a light on another approach to consider, and that is to create POJO (e.g. data model, JavBean) of the object that the JSON represents then using a JSON serializer, like Gson from Google, to convert it to a JSON String.
UserCredentials uc = new UserCredentials ();
//set the values
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(uc);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With