rocker
rocker

Reputation: 69

Spring Unit test with assertions exceptions Java

I am trying to test a Spring Controller which has method called getProductById. I have some exception which i do not uderstand. I will copy stack trace. I am still learning and i do not know if a make things OK.

@Controller
    @RequestMapping("books")
    public class BookController {

        @Autowired
        BookService bookService;
    @RequestMapping("/product")
        public String getProductById(@RequestParam("id") String productId, Model model) {
            model.addAttribute("allBooks", bookService.getBookById(productId));
            return "book";
        }

    }

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/applicationContext.xml" })
@WebAppConfiguration
@RequestMapping("books")
public class BookControllerTest {

    @Mock
    private BookService bookService;

    @InjectMocks
    private BookController bookController;

    private MockMvc mockMvc;

    @Before
    public void before() {
        MockitoAnnotations.initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(bookController).build();
    }
@Test
    public void testGetProductById() {
        Book book = new Book("3", "book", "book", 5253);
        String id = book.getId();
        assertNotNull("Object can not have null id ", id);

        Book searchedBook = bookService.getBookById(id);
        Assertions.assertThat(searchedBook).isNotNull();

        assertTrue("Found book id should be equal to id being searched", searchedBook.getId().compareTo(id) == 3);
    }

java.lang.AssertionError: expecting actual value not to be null
    at org.fest.assertions.Fail.failure(Fail.java:228)
    at org.fest.assertions.Fail.fail(Fail.java:167)
    at org.fest.assertions.Fail.failIfActualIsNull(Fail.java:100)
    at org.fest.assertions.GenericAssert.isNotNull(GenericAssert.java:238)
    at com.book.controller.test.BookControllerTest.testGetProductById(BookControllerTest.java:61)
    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:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    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:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Upvotes: 0

Views: 10894

Answers (1)

Florian Schaetz
Florian Schaetz

Reputation: 10662

 Book searchedBook = bookService.getBookById(id);
 Assertions.assertThat(searchedBook).isNotNull();

You are asserting that the you will get a book from your bookservice, but this is not the case, as your exception shows:

java.lang.AssertionError: expecting actual value not to be null

Obviously, searchedBook is null. The reason for that is simple: Why shouldn't it be? Your bookService is a Mock object and you never tell that mock to return anything specific, so it will probably always return null.

In other words, what you are doing is this:

  1. "Hey, create me a mock object - an object that pretends to be a bookservice"
  2. "Hey, mock object, give me the book with id X"
  3. Mock Object: urm? What? You never told me what to do when you ask me that. Sorry, the only thing I got here is null. Have fun with it.

Testing the behavior of a mock doesn't make sense anyway. Normally you tell the mock to do something specific so that you are able to test something else. Testing an object that pretends to be another object... what for?

In your case, you probably want to test your bookController and for that you'll need the mock of bookservice to behave in a certain way (because the real bookservice probably depends on a database or something like this).

Upvotes: 7

Related Questions