Tony P
Tony P

Reputation: 19

NullPointerException when calling method in Mockito test

I'm working on setting up jUnit tests with Mockito for a project. I'm having trouble when calling a method in the System Under Test (DrawingService). Mocks include a Drawing and an IDrawingRepository.

I'm new to TDD, unit testing, and mocking in general, so maybe I'm making some noob mistake? Any help would be greatly appreciated.

Here's the test class:

public class DrawingServiceTest {

    private DrawingService drawingService;
    private Drawing drawing;
    private IDrawingRepository repository;
    private String drawingName;

    @Before // Executed before each @Test
    public void setUp(){
        drawingService = new DrawingService();
        drawing = mock(Drawing.class);
        repository = mock(IDrawingRepository.class);
    }

    @After // Executed after each @Test
    public void tearDown(){
        //clean up code
    }

    @Test
    public void getDrawingTest() throws DrawingNotFoundException{
        drawingName = "A drawing name that exists";

        System.out.println("drawing name is: " + drawingName);
        when(repository.findByName(drawingName)).thenReturn(drawing);

        System.out.println("calling DrawingService.getDrawing(" + drawingName +")");
        drawingService.getDrawing(drawingName); // The test doesn't continue past this line

        System.out.println("verifying repository.findByName(" + drawingName +") is called");
        verify(repository).findByName(drawingName);

    }

Here's the System Under Test:

@Service ("iDrawingService")
public class DrawingService implements IDrawingService {

    @Autowired
    private IDrawingRepository repository;  

    public List<Drawing> getDrawings() {
        return (List<Drawing>) repository.findAll();
    }

    public Drawing getDrawing(String strName) throws DrawingNotFoundException{
        Drawing drawing = repository.findByName(strName); //this line throws the NullPointerException
        if(drawing == null){
            throw new DrawingNotFoundException("No drawing found for name " + strName);
        }
        return drawing;
    }

}

Upvotes: 1

Views: 2508

Answers (2)

LanceP
LanceP

Reputation: 994

Instead of using @before and @After in your test, you can simply annotate your subject with @InjectMocks and all of your mocked objects with @Mock.

With @InjectMocks you don't even need getters and setters on the subject. In your tests you never tie repository to the subject.

@RunWith(MockitoJUnitRunner.class)
public class DrawingServiceTest {

     @InjectMocks private DrawingService drawingService;
     @Mock private Drawing drawing;
     @Mock private IDrawingRepository repository;
     private String drawingName;

Upvotes: 0

caffeine_inquisitor
caffeine_inquisitor

Reputation: 727

In prod, your class will have IDrawingRepository wired by spring. This is not the case with your test (unit test). You will need to hook it up manually. Your options are:

  1. Make it as constructor injected
  2. Expose a setter for IDrawingRepository

I personally would go with constructor injection, as it is required by your class to work properly. Your class can be tested easily too.

Upvotes: 4

Related Questions