春天& Mockito:在单元测试中调用实际对象

时间:2017-01-13 18:10:21

标签: java spring unit-testing junit mockito

这是我要测试的课程,

    public class AuthErrorResponseWriter  {

        @Autowired
        TransResponse svcResponse;


        @Override
        public void writeResponse(HttpServletResponse response) {


            //Set the Http status
            response.setStatus(HttpStatus.FORBIDDEN.value());
            svcResponse.setMessage(Constants.AUTHENTICATION_ERROR);
            svcResponse.setStatus(HttpStatus.FORBIDDEN.toString());

            ObjectMapper mapper = new ObjectMapper();

            //Write the response
            try {
                Writer writer = response.getWriter();
                writer.write(mapper.writeValueAsString(svcResponse));
                writer.flush();
                writer.close();
            } catch (IOException ioex) {
                logger.error("Problem producing authentication error http response",ioex);  
            }
    }

}

我写的单元测试代码如下,

RunWith(SpringRunner.class)
@WebMvcTest({AuthErrorResponseWriter  .class})
@ComponentScan("com.demo.service")
public class AuthErrorResponseWriterTest {

    @Mock
    HttpServletResponse responseMock;


    @Before 
    public void setUp(){
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testResponse(){

        TransResponse mockResponse = new TransResponse();

        mockResponse.setMessage(Constants.AUTHENTICATION_ERROR);
        mockResponse.setStatus(HttpStatus.FORBIDDEN.toString());

        AuthErrorResponseWriter   authErrorWriter = new AuthErrorResponseWriter  (); 
        PrintWriter writerMock = mock(PrintWriter.class);

        try {
            when(responseMock.getWriter()).thenReturn(writerMock);
        } catch (IOException ioex) {
            //assertTrue(false);
        }
        authErrorWriter.writeResponse(responseMock);
        verify(responseMock).setStatus(HttpStatus.FORBIDDEN.value());

    }

}

当我执行这个Junit时,我得到

的空指针异常
  

svcResponse.setMessage(Constants.AUTHENTICATION_ERROR);

svcResponse为空,即使我已经嘲笑过它。

请有人指出我为什么不拿起模拟对象并寻找实际的。

另外,如果我写Junit是正确的方法吗?

2 个答案:

答案 0 :(得分:2)

你可能想要使用Mockito的跑步者而不是Spring(从我看到的,你根本不需要Spring的背景):

@RunWith(MockitoJUnitRunner.class)
public class SubscriptionServiceTest {

    @InjectMocks
    private AuthErrorResponseWriter authErrorResponseWriter;

    @Mock
    TransResponse svcResponse;

    @Mock
    HttpServletResponse responseMock;

    ....

    authErrorWriter.writeResponse(responseMock);

答案 1 :(得分:1)

  

svcResponse为空,即使我已经嘲笑过它。

不,你没有嘲笑它。这就是您在代码中所做的事情:

TransResponse mockResponse = new TransResponse();
mockResponse.setMessage(Constants.AUTHENTICATION_ERROR);
mockResponse.setStatus(HttpStatus.FORBIDDEN.toString());

你应该做的是这样的事情:

@Mock
private TransResponse mockResponse;

你必须像这样在Target类中注入模拟:

@InjectMocks
private AuthErrorResponseWriter authErrorWriter;

并使用authErrorWriter而不是在测试中创建类的新实例。

然后你可以这样做:

Mockito.doNothing().when(mockResponse).setMessage(Constants.AUTHENTICATION_ERROR);