I'm learning to makes APIs. I'm trying to run a test on my Get request, but keep getting a Null Pointer Exception in my test class. What did I miss?
I'm using Spring Boot/Maven/Java 11. This is a very basic setup (as far as I know) as I have just begun to dip my toe into the world of Spring Boot.
Please see code below:
Controller Test Class:
package ControllerTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
public class StatControllerTest {
#Autowired
private MockMvc mockMvc;
#Test
public void testGetResponse()
throws Exception {
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders
.get("/get");
ResultMatcher contentMatcher = MockMvcResultMatchers.content()
.string("GET Response");
mockMvc.perform(builder).andExpect(contentMatcher).andExpect(MockMvcResultMatchers.status().isOk());
}
}
Controller Class:
package apiPackage;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
#RestController
public class StatController {
#RequestMapping("/")
public String index(){
return "Welcome to the SilverSnacks Stat Sheet!";
}
#GetMapping("/get")
public #ResponseBody ResponseEntity<String> get(){
return new ResponseEntity<String>("GET Response", HttpStatus.OK);
}
#GetMapping("/get/{id}")
public #ResponseBody ResponseEntity<String> getById(#PathVariable String id){
return new ResponseEntity<String>("GET Response:" + id, HttpStatus.OK);
}
#PutMapping("/put")
public #ResponseBody ResponseEntity<String> put(){
return new ResponseEntity<String>("PUT Response", HttpStatus.OK);
}
#PostMapping("/post")
public #ResponseBody ResponseEntity<String> post(){
return new ResponseEntity<String>("POST Response", HttpStatus.OK);
}
#DeleteMapping("/delete")
public #ResponseBody ResponseEntity<String> delete(){
return new ResponseEntity<String>("DELETE Response", HttpStatus.OK);
}
#PatchMapping("/patch")
public #ResponseBody ResponseEntity<String> patch(){
return new ResponseEntity<String>("PATCH Response", HttpStatus.OK);
}
}
Error Output:
java.lang.NullPointerException
at ControllerTest.StatControllerTest.testGetResponse(StatControllerTest.java:26)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
try to add the following annotation to the StatControllerTest
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
public class StatControllerTest {
#Autowired
private MockMvc mockMvc;
....
}
Related
So i have searched all related questions here and found no answer that worked on mine. With that being said I am trying to unit test my spring-boot application with Mockito.
Here is my controller and the function i am trying to test.
#RestController
public class UserController {
#Autowired
UserRepository userRepository;
#GetMapping("/user")
public List<User> getAllUsers() {
return userRepository.findAll();
}
#GetMapping("/user/{id}")
public User getUser(#PathVariable Integer id) {
return userRepository.findById(id).get();
}
I am trying to test getUser function
here is my Test Controller
#RunWith(SpringJUnit4ClassRunner.class)
public class UserControllerTest {
private MockMvc mockMvc;
#MockBean
private UserController userController;
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
}
#Test
public void getUserTest() throws Exception{
mockMvc.perform(get("/user/100").contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith("application/json"))
.andExpect(jsonPath("$.role").value("deliverer"));
}
So firstly when I run this i get following error
java.lang.AssertionError: Content type not set
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:37)
at org.springframework.test.util.AssertionErrors.assertTrue(AssertionErrors.java:70)
at org.springframework.test.util.AssertionErrors.assertNotNull(AssertionErrors.java:106)
at org.springframework.test.web.servlet.result.ContentResultMatchers.lambda$contentTypeCompatibleWith$1(ContentResultMatchers.java:103)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:196)
at eldercare.RESTapi.controller.UserControllerTest.getUserTest(UserControllerTest.java:57)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
with following data being printed
MockHttpServletResponse:
Status = 200
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
I have tested putting #ResponseBody in my Controller does not make any difference. I have also tested as stated in other post #RequestMapping(value="/user/{id}", method= RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) that doesn't work either still get the same error.
If I dont have this check .andExpect(content().contentTypeCompatibleWith("application/json")) then i get the error stating java.lang.AssertionError: No value at JSON path "$.role"
I think you should be mocking the UserRepository and not the UserController.
I want to unit test rentBook method that is rensposible for renting.
Here is the #Service
package bookrental.service.book.rentals;
import bookrental.model.account.User;
import bookrental.model.book.Book;
import bookrental.model.book.BookRentals;
import bookrental.repository.account.UserRepository;
import bookrental.repository.book.BookRepository;
import bookrental.repository.book.BookRentalsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
#Service
public class BookRentalService {
private final UserRepository userRepository;
private final BookRepository bookRepository;
private final BookRentalsRepository bookRentalsRepository;
#Autowired
public BookRentalService(BookRepository bookRepository, BookRentalsRepository bookRentalsRepository, UserRepository userRepository) {
this.bookRepository = bookRepository;
this.bookRentalsRepository = bookRentalsRepository;
this.userRepository = userRepository;
}
public String rentBook(int userID, int bookID) {
if (userRepository.doesAccountExistsWithGivenID(userID)) {
if (bookRepository.doesBookExistsWithGivenID(bookID)) {
Book bookToRent = bookRepository.findOne(bookID);
if (bookToRent.isAvailable()) {
updateBookAvailabilityAndSaveToDb(bookToRent);
BookRentals preparedBookToRent = prepareBookToRent(userID, bookID);
bookRentalsRepository.save(preparedBookToRent);
} else {
throw new IllegalArgumentException("Book is not available");
}
} else {
throw new IllegalArgumentException("Book does not exist!");
}
} else {
throw new IllegalArgumentException("Account does not exist!");
}
return "Book was rented";
}
private BookRentals prepareBookToRent(int userID, int bookID) {
return new BookRentals(new Book(bookID), new User(userID));
}
private void updateBookAvailabilityAndSaveToDb(Book bookToRent) {
bookToRent.setAvailable(false);
bookRepository.save(bookToRent);
}
public List<BookRentals> findAllRentals() {
List<BookRentals> rentedBooks = new ArrayList<>();
bookRentalsRepository.findAll().forEach(rentedBooks::add);
return rentedBooks;
}
}
I tried to unit test it, but getting NPE. I do not know what I am doing wrong.
package bookrental.service.book.rentals;
import bookrental.model.account.User;
import bookrental.model.book.Book;
import bookrental.model.book.BookRentals;
import bookrental.repository.book.BookRentalsRepository;
import bookrental.repository.book.BookRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static org.junit.Assert.*;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
#RunWith(MockitoJUnitRunner.class)
public class BookRentalServiceTest {
#Mock
BookRentalsRepository bookRentalsRepository;
#Mock
BookRepository bookRepository;
#InjectMocks
BookRentalService bookRentalService;
#Test
public void rentBook() {
Book book = createDummyBook();
User user = createDummyUser();
BookRentals bookToRent = createDummyRentedBook(user, book);
when(bookRentalsRepository.save(bookToRent)).thenReturn(bookToRent);
bookRentalService.rentBook(user.getId(), book.getId());
verify(bookRentalsRepository).save(bookToRent);
verify(bookRentalService, times(1)).rentBook(user.getId(), book.getId());
}
#Test
public void findAllRentals() {
}
private Book createDummyBook() {
return new Book(0, "W pustyni i w puszczy", "Henryk Sienkiewicz", "dramat", true);
}
private BookRentals createDummyRentedBook(User user, Book book) {
return new BookRentals(book, user);
}
private User createDummyUser() {
return new User(0, "must", "123");
}
}
Stacktrace:
java.lang.NullPointerException
at bookrental.service.book.rentals.BookRentalService.rentBook(BookRentalService.java:30)
at bookrental.service.book.rentals.BookRentalServiceTest.rentBook(BookRentalServiceTest.java:38)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
///
EDIT
#Test
public void rentBook() {
Book book = createDummyBook();
User user = createDummyUser();
BookRentals bookToRent = createDummyRentedBook(user, book);
when(userRepository.doesAccountExistsWithGivenID(user.getId())).thenReturn(true);
when(bookRepository.doesBookExistsWithGivenID(book.getId())).thenReturn(true);
when(bookRepository.findOne(book.getId())).thenReturn(book);
when(userRepository.findOne(user.getId())).thenReturn(user);
String expected = "Book was rented";
assertEquals(expected, bookRentalService.rentBook(user.getId(), book.getId()));
verify(bookRentalsRepository, times(1)).save(bookToRent);
}
STACKTRACE:
Argument(s) are different! Wanted:
bookRentalsRepository.save(
bookrental.model.book.BookRentals#7574b32f
);
-> at bookrental.service.book.rentals.BookRentalServiceTest.rentBook(BookRentalServiceTest.java:48)
Actual invocation has different arguments:
bookRentalsRepository.save(
bookrental.model.book.BookRentals#1c62c511
);
-> at bookrental.service.book.rentals.BookRentalService.rentBook(BookRentalService.java:36)
Comparison Failure: <Click to see difference>
Argument(s) are different! Wanted:
bookRentalsRepository.save(
bookrental.model.book.BookRentals#7574b32f
);
-> at bookrental.service.book.rentals.BookRentalServiceTest.rentBook(BookRentalServiceTest.java:48)
Actual invocation has different arguments:
bookRentalsRepository.save(
bookrental.model.book.BookRentals#1c62c511
);
-> at bookrental.service.book.rentals.BookRentalService.rentBook(BookRentalService.java:36)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488)
at bookrental.service.book.rentals.BookRentalServiceTest.rentBook(BookRentalServiceTest.java:48)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
From the stack trace, it seems it fails because you didn't mock also the user repository.
Add the following:
#Mock
UserRepository userRepository;
...
when(userRepository.doesAccountExistsWithGivenID(user.getId()).thenReturn(true);
I'm trying to test my simple rest controller method to get all offers but i always get java.lang.AssertionError: Status Expected :200 Actual :404. I don't know if there is problem with mocking or finding my component. I was trying to find solution in other posts but none of them was matching to my problem. Any ideas?
My Service:
#Service
#Transactional
class OfferServiceImpl implements OfferService {
private OfferRepository offerRepository;
#Autowired
public OfferServiceImpl(OfferRepository offerRepository) {
this.offerRepository = offerRepository;
}
#Override
public List<Offer> getAll(){
return (List<Offer>) offerRepository.findAll();
}
My Controller:
#RestController
#RequestMapping("/api/offers")
class OfferRestController {
private OfferService offerService;
#Autowired
public OfferRestController(OfferService offerService) {
this.offerService = offerService;
}
#GetMapping
List<Offer> getAllOffers(){
return offerService.getAll();
}
My Test Class:
#RunWith(SpringRunner.class)
#WebMvcTest(value = OfferRestController.class)
public class OfferControllerIntegrationTest {
private Offer offer1;
private Offer offer2;
#MockBean
private OfferService offerServiceMock;
#Autowired
private WebApplicationContext webApplicationContext;
#Autowired
private MockMvc mvc;
#Before
public void setUpOffers(){
offer1 = new Offer("Java Dev",
4000,
5000,
"CEO",
"Java",
"Lorem ipsum",
"user#gmail.com",
true);
offer2 = new Offer("PHP Dev",
4000,
5000,
"CEO",
"PHP",
"Lorem ipsum",
"user#gmail.com",
true);
}
#Before
public void setUp() {
this.mvc = standaloneSetup(new OfferRestController(offerServiceMock))
.alwaysExpect(MockMvcResultMatchers.content()
.contentType("application/json;charset=UTF-8"))
.defaultRequest(get("/").accept(MediaType.APPLICATION_JSON))
.alwaysExpect(status().isOk())
.build();
this.mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.alwaysDo(print())
.build();
}
#Test
public void givenOffers_whenGetOffers_thenReturnJsonArray() throws Exception{
List<Offer> allOffers= Arrays.asList(offer1,offer2);
given(offerServiceMock.getAll()).willReturn(allOffers);
mvc.perform(get("/api/offers")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$",hasSize(2)))
.andExpect(jsonPath("$[0].name").value(offer1.getName()))
.andExpect(jsonPath("$[1].name").value(offer2.getName()))
.andDo(print());
verify(offerServiceMock,times(1)).getAll();
verifyNoMoreInteractions(offerServiceMock);
}
}
My App:
#SpringBootApplication
#EntityScan(basePackageClasses = {App.class, Jsr310JpaConverters.class})
#ComponentScan({"com"})
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
And my problem:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /api/offers
Parameters = {}
Headers = {Content-Type=[application/json]}
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type =
org.springframework.web.servlet.resource.ResourceHttpRequestHandler
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 404
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: Status
Expected :200
Actual :404
<Click to see difference>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:619)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:178)
at brozek.com.offer.OfferControllerIntegrationTest.givenOffers_whenGetOffers_thenReturnJsonArray(OfferControllerIntegrationTest.java:89)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Usually integration test setup should mock the controller created in the test Spring context with #WebMvcTest(value = OfferRestController.class). The usual syntax is:
#RunWith(SpringRunner.class)
#WebMvcTest(value = OfferRestController.class)
#AutoConfigureMockMvc
public class OfferRestControllerTest {
#MockBean
private OfferService offerService;
#Autowired
private MockMvc mvc;
}
In your test it's pointless to set Content-Type on GET request which has no body, remove
.contentType(MediaType.APPLICATION_JSON)
Starting from Spring 4.1 it's not necessary to use #Autowired on single constructor. You can simplify your code by removing #Autowired here:
public OfferServiceImpl(OfferRepository offerRepository) {
this.offerRepository = offerRepository;
}
I have created an rest api and tested via postman and able to get success response as expected. Now i have created Junit test case for the above api but while executing getting "java.lang.AssertionError: Status expected:<200> but was:<415> ". Not able to figure out why this exception is happening.
I'm new to both Mockito and MockMVC so any help would be appreciated.
Below is my test class
package com.example.demo.hystricks;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.io.Serializable;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import org.apache.commons.lang.SerializationUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.example.demo.DemoController;
import com.example.demo.DemoService;
import com.example.demo.InputModel;
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = DemoController.class)
public class DemoControllerTest {
private MockMvc mockMvc;
#InjectMocks
private DemoController demoController;
#MockBean
private DemoService demoService;
#MockBean
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
DemoController demoController = new DemoController(demoService);
this.mockMvc = MockMvcBuilders
.standaloneSetup(demoController).
setMessageConverters(mappingJackson2HttpMessageConverter).build();
}
#Test
public void postData() throws Exception {
InputModel inputModel = new InputModel("12345","Test","CSC",getEventTime());
System.out.println("before api....");
RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/demoService")
.accept(MediaType.APPLICATION_JSON)
.content(inputModel.toString())
.contentType(MediaType.APPLICATION_JSON);
mockMvc.perform(requestBuilder)
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk());
System.out.println("after api....");
}
private LocalDateTime getEventTime() {
Instant instant = Instant.ofEpochMilli(Instant.now().toEpochMilli());
LocalDateTime eventTimestamp = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return eventTimestamp;
}
}
My Rest Controller
#RestController
public class DemoController {
private static final Logger LOGGER = LoggerFactory.getLogger(DemoController.class);
public final DemoService demoService;
public DemoController(DemoService demoService) {
this.demoService = demoService;
}
#RequestMapping(value = "demoService",method = RequestMethod.POST)
public ResponseEntity<String> postData(
#RequestBody InputModel inputModel){
LOGGER.info("DemoService Entered successfully");
demoService.postData(inputModel.getId(),inputModel.getName(),
inputModel.getDepartment(), inputModel.getJoinDate());
LOGGER.info("DemoService Exited successfully");
return new ResponseEntity<String>("success",HttpStatus.OK) ;
}
}
Console Message before api:
>2018-10-16 12:15:49.391 WARN 6200 --- [ main] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported]
2018-10-16 12:15:49.437 INFO 6200 --- [ Thread-3] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext#5023bb8b: startup date [Tue Oct 16 12:15:48 IST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext#76a4ebf2
Failure Stack Trace:
>java.lang.AssertionError: Status expected:<200> but was:<415>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:619)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:178)
at com.example.demo.hystricks.DemoControllerTest.postData(DemoControllerTest.java:68)
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.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
The issue is on this line:
#MockBean
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
You are mocking this converter. Create a instance using new instead:
this.mockMvc = MockMvcBuilders
.standaloneSetup(controller).
setMessageConverters(new MappingJackson2HttpMessageConverter()).build();
Or as rightly mentioned by M. Dienum, you can do away with the below 2 lines from setUp() method and it'll work:
DemoController demoController = new DemoController(demoService);
this.mockMvc = MockMvcBuilders
.standaloneSetup(demoController).
setMessageConverters(mappingJackson2HttpMessageConverter).build();
After doing all this if you run into 400 error then your toString() method isn't producing valid json.
guys. I'm testing method and in test it's name is testGetAuthorizedUserPublicInfo. This method have to return an User object. (So i created getUser method which return our new user).
Then after calling some methods on mockMvc objects try to perform get method (url is the same like in Controller class).
But i getting 500 response (instead of 200).
Can anyone say where is my mistake?? it would be really great )
`
package com.softserve.academy.spaced.repetition.controller;
import com.softserve.academy.spaced.repetition.controller.handler.ExceptionHandlerController;
import com.softserve.academy.spaced.repetition.domain.Account;
import com.softserve.academy.spaced.repetition.domain.Person;
import com.softserve.academy.spaced.repetition.domain.User;
import com.softserve.academy.spaced.repetition.domain.enums.AccountStatus;
import com.softserve.academy.spaced.repetition.domain.enums.AuthenticationType;
import com.softserve.academy.spaced.repetition.domain.enums.ImageType;
import com.softserve.academy.spaced.repetition.domain.enums.LearningRegime;
import com.softserve.academy.spaced.repetition.service.UserService;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.context.MessageSource;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.Date;
import java.util.Locale;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#RunWith(MockitoJUnitRunner.class)
public class UserControllerTest {
private MockMvc mockMvc;
private static final long USER_ID = 1L;
#InjectMocks
UserController userController;
#Mock
UserService userService;
#Before
public void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(userController)
.setControllerAdvice(new ExceptionHandlerController())
.build();
}
#Test
public void testGetAuthorizedUserPublicInfo() throws Exception {
when(userService.getAuthorizedUser()).thenReturn(getUser());
mockMvc.perform(get("/api/user/details")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.id", Matchers.is(1)));
}
private User getUser() {
Account account;
Person person;
User user;
account = new Account();
account.setId(USER_ID);
account.setPassword("12345678");
account.setEmail("a#a.a");
account.setAuthenticationType(AuthenticationType.LOCAL);
account.setStatus(AccountStatus.ACTIVE);
account.setDeactivated(false);
account.setLastPasswordResetDate(new Date());
account.setLearningRegime(LearningRegime.BAD_NORMAL_GOOD_STATUS_DEPENDING);
account.setCardsNumber(1);
person = new Person();
person.setId(USER_ID);
person.setFirstName("firstname");
person.setLastName("lastname");
person.setImageType(ImageType.NONE);
user = new User();
user.setId(USER_ID);
user.setAccount(account);
user.setPerson(person);
return user;
}
}
`
here is what i've got after executing this test method
`
java.lang.AssertionError: Status
Expected :200
Actual :500
<Click to see difference>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:54)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:81)
at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:664)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
at com.softserve.academy.spaced.repetition.controller.UserControllerTest.testGetAuthorizedUserPublicInfo(UserControllerTest.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Process finished with exit code 255
`