I am trying to test my services using Junit and Mockito. I am able to mock the service and get the response from the Resource class. The response body is having some data of JSON format which is of the object type. I am trying to get the data from the object using ObjectMapper of Jackson library using spring boot.
EmployeeResource.java
package com.ems.resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.ems.exception.InvalidInputDataException;
import com.ems.service.EmployeeService;
import com.ems.service.UserService;
import com.ems.util.EmailUtils;
import com.ms.base.beans.EmailObject;
import com.ms.base.entity.Employee;
import com.ms.base.entity.User;
@RestController
@RequestMapping(path = "/employee")
public class EmployeeResource
{
final Logger logger = LogManager.getLogger(EmployeeResource.class);
final String EMAIL_QUEUE_NAME = "EmailQueue";
@Autowired
JmsTemplate jmsTemplate;
@Autowired
EmployeeService employeeService;
@Autowired
UserService userService;
@RequestMapping(path = "/list", method = {RequestMethod.GET, RequestMethod.POST})
@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_HR', 'ROLE_EMP_CRUD')")
public ResponseEntity<Object> listEmployees() throws Exception
{
Map responseMap = new HashMap();
List<Employee> employees = employeeService.getEmployees();
responseMap.put("employees", employees);
responseMap.put("status", HttpStatus.OK.value());
responseMap.put("statusName", HttpStatus.OK.name());
return new ResponseEntity(responseMap, HttpStatus.OK);
}
}
EmployeeService.java
package com.ems.service;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ems.repository.EmployeeRepository;
import com.ms.base.entity.Employee;
@Service
public class EmployeeService
{
@Autowired
EmployeeRepository employeeRepository;
@Autowired
UserService userService;
public List<Employee> getEmployees()
{
return employeeRepository.findAll();
}
}
EmployeeResourceTest.java
package com.ems.resource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.ResponseEntity;
import com.ems.service.EmployeeService;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.google.gson.JsonObject;
import com.ms.base.entity.Employee;
@RunWith(JUnitPlatform.class)
@ExtendWith(MockitoExtension.class)
public class EmployeeResourceTest
{
@InjectMocks
private EmployeeResource employeeResource;
@Mock
private EmployeeService employeeService;
@Test
public void getAllEmployees() throws Exception
{
// given
Employee employee1 = new Employee();
employee1.setId(1L);
employee1.setName("Vineel Pellella");
employee1.setDateOfBirth(new Date(780537600));
employee1.setDateOfJoining(new Date());
employee1.setDesignation("ROLE_ADMIN");
employee1.setWorkLocation("Hyderabad");
employee1.setContactNo(9985896040L);
employee1.setEmail("[email protected]");
List<Employee> employees = new ArrayList<Employee>();
employees.addAll(Arrays.asList(employee1));
when(employeeService.getEmployees()).thenReturn(employees);
// when
ResponseEntity<Object> result = employeeResource.listEmployees();
// then
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
JsonParser parser = objectMapper.createParser(result.getBody().toString());
Map respMap = objectMapper.readValue(parser, Map.class);
// System.out.println(emp.getDateOfBirth());
assertThat(result.getBody()).isNotNull();
verify(employeeResource).listEmployees();
verify(employeeService).getEmployees();
}
}
Employee.java
package com.ms.base.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data
@NoArgsConstructor
public class Employee implements Serializable
{
private static final long serialVersionUID = -3732596549369515261L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String designation;
private Date dateOfBirth;
private Date dateOfJoining;
private String workLocation;
@Column(unique = true)
private Long contactNo;
@Column(unique = true)
private String email;
private Date dateOfLeaving;
}
The employeeRepository is just an interface of JPARepository.
StackTrace
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('s' (code 115)): was expecting double-quote to start field name
at [Source: (String)"{statusName=OK, employees=[Employee(id=1, name=Vineel Pellella, designation=null, dateOfBirth=Sat Jan 10 06:18:57 IST 1970, dateOfJoining=Mon Sep 27 15:34:45 IST 2021, workLocation=Hyderabad, contactNo=9985896040, [email protected], dateOfLeaving=null)], status=200}"; line: 1, column: 3]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2337)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:710)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:635)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddName(ReaderBasedJsonParser.java:1814)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextFieldName(ReaderBasedJsonParser.java:941)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:582)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:437)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:32)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3516)
at com.ems.resource.EmployeeResourceTest.getAllEmployees(EmployeeResourceTest.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.util.ArrayList.forEach(Unknown Source)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.util.ArrayList.forEach(Unknown Source)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
at org.junit.platform.runner.JUnitPlatform.run(JUnitPlatform.java:139)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Result of result.getBody().toString()
{statusName=OK, employees=[Employee(id=1, name=Vineel Pellella, designation=ROLE_ADMIN, dateOfBirth=Sat Jan 10 06:18:57 IST 1970, dateOfJoining=Mon Sep 27 17:22:09 IST 2021, workLocation=Hyderabad, contactNo=9985896040, [email protected], dateOfLeaving=null), Employee(id=2, name=Vineel Pellella2, designation=ROLE_ADMIN, ROLE_HR, dateOfBirth=Sat Jan 10 06:18:57 IST 1970, dateOfJoining=Mon Sep 27 17:22:09 IST 2021, workLocation=Bengaluru, contactNo=9985896041, [email protected], dateOfLeaving=null), Employee(id=3, name=Vineel Pellella3, designation=ROLE_ADMIN, ROLE_HR, dateOfBirth=Sat Jan 10 06:18:57 IST 1970, dateOfJoining=Mon Sep 27 17:22:09 IST 2021, workLocation=Chennai, contactNo=9985896042, [email protected], dateOfLeaving=null)], status=200}
CodePudding user response:
Check that you are passing valid JSON string to the parser. As mentioned in the error logs its not valid JSON, Unexpected character ('s' (code 115)): was expecting double-quote to start field name
. Or you can add the flag JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES
to allow un-quoted field name handling.
CodePudding user response:
After long research, I tried the below approach which is automatically converting the invalid JSON to valid JSON.
ObjectMapper objectMapper = new ObjectMapper();
String respData = objectMapper.writeValueAsString(result.getBody());
Map respMap = objectMapper.readValue(respData, Map.class);