junit test : java.lang.ClassCastException - unit-testing

I am trying to implement junit testing with spring data jpa application. On controller level I am trying to implement unit testing. But I am getting Test failure class cast exception error.
DepartmentController.java
#RestController
#RequestMapping("/api.spacestudy.com/SpaceStudy/Control/SearchFilter")
public class DepartmentController {
#Autowired
DepartmentService depService;
#CrossOrigin(origins = "*")
#GetMapping("/loadDepartments")
public ResponseEntity<Set<Department>> findDepName() {
Set<Department> depname = depService.findDepName();
return ResponseEntity.ok(depname);
}
}
Junit test class
#RunWith(SpringRunner.class)
#WebMvcTest(DepartmentController.class)
public class SpaceStudyControlSearchFilterApplicationTests {
#Autowired
DepartmentController depController;
#Autowired
private MockMvc mockMvc;
#MockBean
DepartmentService depService;
#SuppressWarnings("unchecked")
Set<Department> mockDepartment = (Set<Department>) new Department(21629, "170330", "Administrative Computer");
#Test
public void findDepNameTest() throws Exception {
Mockito.when(depService.findDepName()).thenReturn( mockDepartment);
RequestBuilder requestBuilder = MockMvcRequestBuilders.get(
"/api.spacestudy.com/SpaceStudy/Control/SearchFilter/loadDepartments").accept(
MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
System.out.println(result.getResponse());
String expected = "{nDeptId: 21629}";
JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), false);
}
}
Junit failure
java.lang.ClassCastException: com.spacestudy.model.Department cannot be cast to java.util.Set
at com.spacestudy.SpaceStudyControlSearchFilterApplicationTests.<init>(SpaceStudyControlSearchFilterApplicationTests.java:39)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
I am new to junit testing. Can any one tell me what I am doing wrong in test?

You are trying to cast a Department to Set<Department> at this line:
Set<Department> mockDepartment = (Set<Department>) new Department(21629, "170330", "Administrative Computer");
This cannot work. Instead you should create an empty set and then add the department, i.e. like this:
Set<Department> mockDepartment = new HashSet<Department>() {{
add(new Department(21629, "170330", "Administrative Computer"));
}};

Related

Mocked repository is null when Mockito testing

I end up with my repository as null when testing a method in a service class. It is unclear what causes this for me.
In my service class I make use of a private RestTemplate that I setup as follows together with repository as #Mocks and service class #Injectmocks on :
...
#InjectMocks
#Spy
WorkService workService;
#Mock
private WorkJobRepository workJobRepository;
...
#Mock
RestTemplateBuilder mockedBuilder= Mockito.mock(RestTemplateBuilder.class);
#Mock
RestTemplate mockedRestTemplate = Mockito.mock(RestTemplate.class);
#BeforeEach
void setUp() {
ReflectionTestUtils.setField(listToPrintService, "restTemplate", mockedRestTemplate);
}
My test case in which repository is not passed (it is null):
#Test
void testGetRequestListToWork() {
ListToWork listToWork = getListToWork();
WorkJob WorkJob = getOneWorkJob();
ResponseEntity<String> responseEntity = getOneResponseEntityString(listToWork);
Mockito.doReturn(responseEntity).when(listToWorkService).getRequestListToWork(listToWork);
Mockito.when(listToWorkService.getRequestListToWork(listToWork)).thenAnswer(new Answer<ResponseEntity<String>>() {
#Override
public ResponseEntity<String> answer(InvocationOnMock invocation) {
return responseEntity;
}
});
String json = responseEntity.getBody().toString();
Mockito.when(listToWorkService.createNewWorkJob(json, listToWork)).thenReturn(WorkJob);
listToWorkService.getRequestListToWork(WorkJob);
assertEquals("xxx", repository.getById(listToWork.getId));
}
Here's the method I am trying to test:
public WorkJob getRequestListToWork(WorkJob WorkJob) {
ListToWork listToWork = new ListToWork(WorkJob.getTemplateId(), WorkJob.getStoreName(), WorkJob.getJobListId(), WorkJob.getId());
ResponseEntity<String> responseEntity = getRequestListToWork(listToWork);
Gson g = new Gson();
String json = responseEntity.getBody().toString();
WorkJob newWorkJob = createNewWorkJob(json,listToWork);
if(newWorkJob.getJobId() != -1 && newWorkJob.getJobState() != 12) {
pollForJobStatus(newWorkJob);
}
return newWorkJob;
}
Can anybody advise? What is causing the repository not to be passed?

Junit Test case : java.lang.exception: json can not be null or empty

I am trying to write Test case for controller using JUnit and mockito. But I am getting error as JSON can not be null or empty. can any one please tell me what I m doing wrong?
DepartmentController
#RestController
#RequestMapping("/api.spacestudy.com/SpaceStudy")
public class DepartmentController {
#Autowired
DepartmentService depService;
#GetMapping("/Control/SearchFilter/loadDepartments")
public ResponseEntity<Set<Department>> findDepName() {
Set<Department> depname = depService.findDepName();
return ResponseEntity.ok(depname);
}
DepartmentControllerTest
#RunWith(SpringJUnit4ClassRunner.class)
public class DepartmentControllerTest {
private MockMvc mockMvc;
#Mock
public DepartmentService depService;
#InjectMocks
DepartmentController departmentController;
#Before
public void setup() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(departmentController).build();
}
#Test(timeout = 10000)
public void findDepNameTest() throws Exception
{
Department dep = new Department();
dep.setsDeptName("ABC");
Set<Department> department = new HashSet<Department>();
department.add(dep);
Mockito.when(depService.findDepName()).thenReturn(department);
mockMvc.perform(get("/api.spacestudy.com/SpaceStudy/LoadDept").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].sDeptName" , is("abc")));
}
}
Failure Trace
java.lang.AssertionError: No value at JSON path "$[0].sDeptName", exception: json can not be null or empty
at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:245)
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:73)
at org.springframework.test.web.servlet.result.JsonPathResultMatchers$1.match(JsonPathResultMatchers.java:87)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
at com.spacestudy.DepartmentControllerTest.findDepNameTest(DepartmentControllerTest.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
I found my mistake. I am giving wrong path for get Request in above code. I changed that path and its working properly.
mockMvc.perform(get("/api.spacestudy.com/SpaceStudy/Control/SearchFilter/loadDepartmentsLoadDept").accept(MediaType.APPLICATION_JSON))

Spring boot testing REST controller with JPA

I am having issues trying to test
THe following REST method
#GetMapping
#RequestMapping("/create")
ResponseEntity<Order> createOrders(#RequestBody String body) {
ObjectMapper mapper = new ObjectMapper();
try{
Map<String,Object> mapBody = mapper.readValue(body,Map.class);
Long cusId = Long.valueOf((int)mapBody.get("customer_id"));
Customer customer = customerRepository.findOne(cusId);
Product product = productRepository.findByProductName((String)mapBody.get("product_name"));
Order order = new Order(customer,product,(int)mapBody.get("quantity"));
orderRepository.saveAndFlush(order);
return new ResponseEntity(order, HttpStatus.OK);
}
catch(Exception e){
e.printStackTrace();
return new ResponseEntity("error with original port", HttpStatus.EXPECTATION_FAILED);
}
}
I have tried numrous things so for and nothing seems to work.
Doing a call to the REST method works fine but it seems I can use either
#AutoConfigureMockMvc or #DataJpaTest in my testing
My code is currently as follows
#SpringBootTest
#AutoConfigureMockMvc
#DataJpaTest
public class OrderTest {
#Autowired
private MockMvc mockMvc;
#Autowired
private ProductRepository productRepositoryTest;
#Autowired
private CustomerRepository customerRepositoryTest;
#Test
public void submitNewOrdersForBricks() {
try {
Customer cus1 = new Customer("cus1");
customerRepositoryTest.saveAndFlush(cus1);
Product pro1 = new Product("brick1","red brick",0.96);
productRepositoryTest.saveAndFlush(pro1);
this.mockMvc.perform(post("/create")
.content("{\"customer_id\":"+cus1.getCustomerId()+",\"product_name\":\"brick1\",\"quantity\":150}")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print()).andExpect(status().isCreated())
.andExpect(jsonPath("$.order_id").value(1));
}
catch(Exception e){
e.printStackTrace();
}
}
}
I have also tried using
when(customerRepository.findOne(cusId)).thenReturn(cus1);
This did not have any effect in my controller.
Please note that the controller method createOrders is only called when I remove #DataJpaTest, but then IDs are not created for customer and product.
Any help would be great.
#DataJpaTest is for repository test. In this case, #DataJpaTest is useless.
And, in test class, you missed
#Autowired
private OrderRepository orderRepository;

Unit test verify method was called inside RxJava's doOnSuccess operator

I have the following code I'm trying to unit test :
if (networkUtils.isOnline()) {
return remoteDataSource.postComment(postId, commentText)
.doOnSuccess(postCommentResponse ->
localDataSource.postComment(postId, commentText))
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.mainThread());
} else {
return Single.error(new IOException());
}
And this is how I'm trying to test it :
#Test
public void postComment_whenIsOnline_shouldCallLocalToPostComment() throws Exception {
// Given
when(networkUtils.isOnline())
.thenReturn(true);
String postId = "100";
String comment = "comment";
Response<PostCommentResponse> response = postCommentResponse();
when(remoteDataSource.postComment(anyString(), anyString()))
.thenReturn(Single.just(response));
// When
repository.postComment(postId, comment);
// Then
verify(localDataSource).postComment(postId, comment);
}
where I fake Response from Retrofit like :
private Response<PostCommentResponse> postCommentResponse() {
PostCommentResponse response = new PostCommentResponse();
response.setError("0");
response.setComment(postCommentResponseNestedItem);
return Response.success(response);
}
but it results to : Actually, there were zero interactions with this mock.
Any ideas ?
EDIT :
#RunWith(MockitoJUnitRunner.class)
public class CommentsRepositoryTest {
#Mock
private CommentsLocalDataSource localDataSource;
#Mock
private CommentsRemoteDataSource remoteDataSource;
#Mock
private NetworkUtils networkUtils;
#Mock
private PostCommentResponseNestedItem postCommentResponseNestedItem;
private CommentsRepository repository;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
BaseSchedulerProvider schedulerProvider = new ImmediateSchedulerProvider();
repository = new CommentsRepository(localDataSource, remoteDataSource, networkUtils, schedulerProvider);
}
// tests
}
When you want to test an Observable you have to subscribe to it so it will start emitting items.
As soon as I used :
TestObserver<Response<PostCommentResponse>> testObserver = new TestObserver<>();
and subscribed to :
repository.postComment(postId, comment)
.subscribe(testObserver);
the test worked as expected.

Spring boot How to access Appconfig properties in test case

I am new to web services and spring boot. I have written a service for which I am now writing a test case.
My application gets Soap request, parses the body and saves contents into database.
My test case tests this service.
When I run the application and send a request from Postman, it runs alright. But when I call my service method from test case, I get nullpointer for JaxBcontext.
I have declared Jaxbcontext in my AppConfig.java (which is annotated with #Configuration and my jaxb is a bean with #Bean annotation) in my service, I have #autowire to use jaxbcontext.
I have pasted code snippets for clarity. Please advise me what I am doing wrongly here.
My test case
public class ReferralExchangeEndpointTest {
ReferralExchangeEndpoint referralExchangeEndpoint = new ReferralExchangeEndpoint();
JAXBContext jbcTest;
Marshaller marshaller;
Unmarshaller unmarshaller;
public ReferralExchangeEndpointTest() throws JAXBException {
}
#Before
public void setUp() throws Exception {
jbcTest = JAXBContext.newInstance(
"our app schema"); // this is working fine, I have replaced schema with this text for posting it in stack.
ObjectFactory factory = new ObjectFactory();
marshaller = jbcTest.createMarshaller();
unmarshaller = jbcTest.createUnmarshaller();
}
#Test
public void send() throws Exception {
File payload = new File("payload.xml");
Object x = unmarshaller.unmarshal(payload);
JAXBElement jbe = (JAXBElement) x;
System.out.println(jbe.getName());
Object test = jbe.getValue();
SendRequestMessage sendRequestMessage = (SendRequestMessage) jbe.getValue();
// Method in test.
referralExchangeEndpoint.send(sendRequestMessage);
}
}
My service class
#Endpoint
public class ReferralExchangeEndpoint {
public static final Logger logger = LoggerFactory.getLogger(ReferralExchangeEndpoint.class);
#Autowired
private JAXBContext jaxbContext;
#Autowired
.
.
.
private Form parseBody(String payLoadBody) {
try {
Unmarshaller um = jaxbContext.createUnmarshaller();
return (Form) um.unmarshal(new StringReader(payLoadBody));
} catch (Exception e) {
throw new RuntimeException("Failed to extract the form from the payload body", e);
}
}
My appconfig file
#Configuration
public class AppConfig {
#Bean
public JAXBContext jaxbContext() throws JAXBException {
return
JAXBContext.newInstance("packagename");
}
#Bean public MessagingService messagingService() {
return new MessagingService();
}
}
Thanks.
Kavitha.
** Solved **
My test case now looks like this.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {AppConfig.class})`
public class ReferralExchangeEndpointTest {
#Autowired
ReferralExchangeEndpoint referralExchangeEndpoint;
#Autowired
private JAXBContext jaxbContext;
private Marshaller marshaller;
private Unmarshaller unmarshaller;
#Before
public void setUp() throws Exception {
marshaller = jaxbContext.createMarshaller();
unmarshaller = jaxbContext.createUnmarshaller();
}
#Test
public void send() throws Exception {
File payload = new File("src/test/resources/payload.xml");
JAXBElement jbe = (JAXBElement) unmarshaller.unmarshal(payload);
SendRequestMessage sendRequestMessage = (SendRequestMessage) jbe.getValue();
JAXBElement<SendResponseMessage> response = referralExchangeEndpoint.send(sendRequestMessage);
//TODO add remaining assertions on response after confirming what should the service return for these attributes.
assertEquals("SiteId wrong in response: ", "siteId", response.getValue().getSiteId());
}
}`