1

My JUnit test case is failing. Error is occurring at line

Mockito.when(blogEntryService.find(1L)).thenReturn(entry);

Failure trace is

java.lang.NullPointerException at com.sample.controller.BlogEntryControllerTest.getExistingBlogEntry(BlogEntryControllerTest.java:72) 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.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:233) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87) 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:71) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

it seems to me that blogEntryService is null

My code is

    /**
 * TODO - Describe purpose and operation of class.
 * 
 * <table border="1" cellpadding="0" cellspacing="0" width="100%">
 * <caption align="center">Edit and Version History</caption>
 * <tr><th>Version</th><th>Date</th><th>Author</th><th>Description</th></tr>
 * <tr><td>1.0</td><td>Jan 17, 2016</td><td>EOV537</td><td>Initial creation.</td></tr>
 * </table>
 */
package com.sample.controller;

import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;

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.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.sample.config.ApplicationConfig;
import com.sample.model.BlogEntry;
import com.sample.service.BlogEntryService;

/**
 * @author EOV537 -
 * @since 1.0
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ApplicationConfig.class})
@WebAppConfiguration
public class BlogEntryControllerTest {

    private MockMvc mockMvc;

    @InjectMocks
    private BlogEntryController blogentryconttroller;

    @Mock
    private BlogEntryService blogEntryService;

    @Autowired
    private WebApplicationContext appCtx;

    @Before
    public void setup() {

        MockitoAnnotations.initMocks(BlogEntryControllerTest.class);
        mockMvc = MockMvcBuilders.webAppContextSetup(appCtx).build();
    }

    @Test
    public void getExistingBlogEntry() throws Exception {

        BlogEntry entry = new BlogEntry();
        entry.setId(1L);
        entry.setTitle("Test Title");

        Mockito.when(blogEntryService.find(1L)).thenReturn(entry);

        mockMvc.perform(MockMvcRequestBuilders.get("/rest/blog-entries/1"))
                .andExpect(MockMvcResultMatchers.jsonPath("$.title", Matchers.is("Test Title")))
                .andExpect(
                        MockMvcResultMatchers.jsonPath("$.links[*].href",
                                Matchers.hasItem(Matchers.endsWith("/blog-entries/1"))))
                .andExpect(MockMvcResultMatchers.status().isOk());
    }

    public void getNonExistingBlogEntry() throws Exception {

        Mockito.when(blogEntryService.find(1L)).thenReturn(null);
        mockMvc.perform(MockMvcRequestBuilders.get("/rest/blog-entries/1")).andExpect(
                MockMvcResultMatchers.status().isNotFound());
    }



}

BlogEntryController.Java

package com.sample.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.sample.assembler.BlogEntryResourceAsm;
import com.sample.model.BlogEntry;
import com.sample.resource.BlogEntryResource;
import com.sample.service.BlogEntryService;

/**
 * @author EOV537 -
 * @since 1.0
 */
@Controller
@RequestMapping(value = "/rest/blog-enteries")
public class BlogEntryController {

    public BlogEntryController() {

    }

    public BlogEntryController(BlogEntryService blogEntryService) {

        this.blogEntryService = blogEntryService;
    }

    private BlogEntryService blogEntryService;

    @RequestMapping(value = "/{blogEntryId}", method = RequestMethod.GET)
    public ResponseEntity<BlogEntryResource> getExsitingBlogEntry(@PathVariable Long blogEntryId) {

        BlogEntry entry = blogEntryService.find(blogEntryId);

        if (entry != null) {
            BlogEntryResource res = new BlogEntryResourceAsm().toResource(entry);
            return new ResponseEntity<BlogEntryResource>(res, HttpStatus.OK);
        } else {
            return new ResponseEntity<BlogEntryResource>(HttpStatus.NOT_FOUND);
        }
    }

}

BlogEntryService.Java

package com.sample.service;

import org.springframework.stereotype.Component;

import com.sample.model.BlogEntry;

/**
 * @author EOv537 -
 * 
 * @since 1.0
 */

public interface BlogEntryService {
    public BlogEntry find(Long id);
}

BlogEntryResource.java

package com.sample.resource;

import org.springframework.hateoas.ResourceSupport;

/**
 * @author EOv537 -
 * @since 1.0
 */
public class BlogEntryResource extends ResourceSupport {

    private String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

}

BlogEntryResourceAsm.java

public class BlogEntryResourceAsm extends ResourceAssemblerSupport<BlogEntry, BlogEntryResource> {

    /**
     * @param controllerClass
     * @param resourceType
     */
    public BlogEntryResourceAsm() {
        super(BlogEntryController.class, BlogEntryResource.class);
        // TODO Auto-generated constructor stub
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.hateoas.ResourceAssembler#toResource(java.lang.Object)
     */
    @Override
    public BlogEntryResource toResource(BlogEntry blogEntry) {

        BlogEntryResource res = new BlogEntryResource();
        res.setTitle(blogEntry.getTitle());
        Link link = ControllerLinkBuilder.linkTo(BlogEntryController.class).slash(blogEntry.getId()).withSelfRel();
        return res;

    }
}

ApplicationConfig.java

/**
 * TODO - Describe purpose and operation of class.
 * 
 * <table border="1" cellpadding="0" cellspacing="0" width="100%">
 * <caption align="center">Edit and Version History</caption>
 * <tr><th>Version</th><th>Date</th><th>Author</th><th>Description</th></tr>
 * <tr><td>1.0</td><td>Jan 17, 2016</td><td>EOV537</td><td>Initial creation.</td></tr>
 * </table>
 */
package com.sample.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**
 * @author EOV537 -
 * @since 1.0
 */
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.sample"})
public class ApplicationConfig extends WebMvcConfigurerAdapter {

    private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/jsp/";

    private static final String VIEW_RESOLVER_SUFFIX = ".jsp";

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("/static/");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

        // viewResolver.setViewClass(InternalResourceViewResolver.class); // NOSONAR
        viewResolver.setPrefix(VIEW_RESOLVER_PREFIX);
        viewResolver.setSuffix(VIEW_RESOLVER_SUFFIX);

        return viewResolver;
    }

}

WebApplint.java

/**
 * TODO - Describe purpose and operation of class.
 * 
 * <table border="1" cellpadding="0" cellspacing="0" width="100%">
 * <caption align="center">Edit and Version History</caption>
 * <tr><th>Version</th><th>Date</th><th>Author</th><th>Description</th></tr>
 * <tr><td>1.0</td><td>Jan 17, 2016</td><td>EOV537</td><td>Initial creation.</td></tr>
 * </table>
 */
package com.sample.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * @author EOV537 -
 * @since 1.0
 */
public class WebApplint implements WebApplicationInitializer {
    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.web.WebApplicationInitializer#onStartup(javax.servlet.ServletContext)
     */
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(ApplicationConfig.class);

        ServletRegistration.Dynamic registration = servletContext.addServlet("DispatcherServlet",
                new DispatcherServlet(rootContext));

        registration.addMapping("/");

        registration.setLoadOnStartup(1);
        servletContext.addListener(new ContextLoaderListener(rootContext));

    }
}

3 Answers 3

1
private MockMvc mockMvc;

@Autowired
@InjectMocks
private BlogEntryController blogentryconttroller;

@Autowired
private WebApplicationContext appCtx;

@Mock
BlogEntryService blogEntryService;

@Before
public void setup() {
    MockitoAnnotations.initMocks(BlogEntryControllerTest.this);
    mockMvc = MockMvcBuilders.webAppContextSetup(appCtx).build();
}

@Test
public void getExistingBlogEntry() throws Exception {
    BlogEntry entry = new BlogEntry();
    entry.setId(1L);
    entry.setTitle("Test Title");
    Mockito.when(blogEntryService.find(1L)).thenReturn(entry);
    mockMvc.perform(MockMvcRequestBuilders.get("/rest/blog-enteries/1"))
            .andExpect(MockMvcResultMatchers.status().isOk());
}
Sign up to request clarification or add additional context in comments.

8 Comments

I want to use annotations @Mock private BlogEntryService blogEntryService; if you see the class I already have that is that approach is not correct?
using your solution BlogEntryService blogEntryService = Mockito.mock(BlogEntryService.class); Mockito is giving me proxy implementation, I don't need to add implementation and intialize but I never understood why @mock did not work.
I did initialize see my code MockitoAnnotations.initMocks(BlogEntryControllerTest.class);
with your solution I am able to move forward 1 step but after test execution it is still failing 2016-01-24 11:21:21 DEBUG TestDispatcherServlet:984 - Could not complete request java.lang.NullPointerException at com.sample.controller.BlogEntryController.getExsitingBlogEntry(BlogEntryController.java:49)
I don't have service implementation that is why I am using mock. Here is link to my repository github.com/satyajitn/rest-service I am doing test driven development so writing test cases before service implemenation
|
0

In BlogEntryController(), blogEntryService is never initialized with a value. in your @Before (setup()) method, initialize blogEntryService:

blogEntryService = new BlogEntryService();

1 Comment

blogEntryService is Interface it can not be resolved into variable. Please see the code
0

Rohit's Answer above helped and resolve original mocking issue following was alternative I tried and it work, but it is just alternative not the solution.

I commented following line

//@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(classes = {ApplicationConfig.class})

from BlogEntryControllerTest.java

I changed setup() method from BlogEntryControllerTest to

@Before
public void setup() {

    // blogEntryService = Mockito.mock(BlogEntryService.class);
    MockitoAnnotations.initMocks(this);
    mockMvc = MockMvcBuilders.standaloneSetup(blogentryconttroller).build();
    //mockMvc = MockMvcBuilders.webAppContextSetup(appCtx).build();

}

Instead of webAppContextSetup it is change to StandaloneSetup and then

updated BlogEntryController and removed default constructor

// public BlogEntryController() {

// }

now there is only 1 constructor

public BlogEntryController(BlogEntryService blogEntryService) {

    this.blogEntryService = blogEntryService;
}

Now when I am executing test mocked blogEntryService is getting injected properly.

When I was using webAppContextSetup then I have to keep default constructor for BlogEntryController. Since it had default constructor, so when I ran test default constructor get executed and blogEntryService remain null and test fail.

Even though I am able to get this working, this is not solution it is just a alternative.

if Someone know how to get this issue resole with webAppContextSetup please post solution.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.