在Mockito测试中调用方法时出现NullPointerException

时间:2016-11-09 21:37:14

标签: java junit mockito

我正在与Mockito一起为项目设置jUnit测试。我在系统测试(DrawingService)中调用方法时遇到了麻烦。模拟包括一个Drawing和一个IDrawingRepository。

我是TDD新手,单元测试和一般的嘲讽,所以也许我做了一些noob错误?任何帮助将不胜感激。

以下是测试类:

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);

    }

以下是受测系统

@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;
    }

}

2 个答案:

答案 0 :(得分:4)

在prod中,你的类将使用Spring连接IDrawingRepository。您的测试(单元测试)不是这种情况。您需要手动连接它。您的选择是:

  1. 将其作为构造函数注入
  2. 为IDrawingRepository公开一个setter
  3. 我个人会选择构造函数注入,因为您的类需要正常工作。您的课程也可以轻松测试。

答案 1 :(得分:1)

您可以使用@before和所有模拟对象@After来简单地注释主题,而不是在测试中使用@InjectMocks@Mock

使用@InjectMocks,您甚至不需要关于此主题的getter和setter。在您的测试中,您永远不会将repository绑定到主题。

@RunWith(MockitoJUnitRunner.class)
public class DrawingServiceTest {

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