java - Mockito ArgumentCaptor 在 verify() 上给出 NullpointerException

标签 java unit-testing servlets junit mockito

我目前正在尝试为我们的 Servlet 创建测试。我 mock 过 HttpServletRequest , HttpServletResponse和一个用作数据库处理程序的对象。在对 doPost 的测试中方法,我的愿望是比较来自 Json 对象的值和发送到数据库对象的 ArrayList 的值。

小服务程序:

public class WidgetStatusServlet extends HttpServlet {

private DBController db = new DBController();

    @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("application/json");
    JsonParser parser = new JsonParser();
    JsonElement tradeElement = parser.parse(request.getParameter("widgetdata"));
    JsonArray json = tradeElement.getAsJsonArray();
    Gson gson = new Gson();
    Type listType = new TypeToken<List<WidgetStatus>>() {
    }.getType();
    ArrayList<WidgetStatus> widgets = gson.fromJson(json, listType);

    Iterator<WidgetStatus> iterator = widgets.iterator();
    System.out.println("Widgets");
    while (iterator.hasNext()) {
        WidgetStatus node = (WidgetStatus) iterator.next();
        System.out.println(node);
    }

    db.addWidgetStatus(widgets);

}

考试:
public class WidgetStatusServletTest {

@Captor
private ArgumentCaptor<ArrayList<WidgetStatus>> captor;

private DBController dbMock = mock(DBController.class);
private HttpServletRequest request = mock(HttpServletRequest.class);
private HttpServletResponse response = mock(HttpServletResponse.class);
Repository repository = mock(Repository.class);`


    @Test
public void doPost_ShouldVerifyWidgetsIsProvided() throws Exception {
    final WidgetStatus widget1 = new WidgetStatus("id1", "div_id1", "5", "5", "1", "2", false);
    final WidgetStatus widget2 = new WidgetStatus("id2", "div_id2", "2", "1", "3", "1", true);

    when(request.getParameter("widgetdata")).thenAnswer(new Answer<String>() {
        @Override
        public String answer(InvocationOnMock invocation) throws Throwable {
            ArrayList<WidgetStatus> array = new ArrayList<WidgetStatus>();
            array.add(widget1);
            array.add(widget2);
            String json = new Gson().toJson(array);
            return json;
        }
    });
    new WidgetStatusServlet().doPost(request, response);
    verify(dbMock).addWidgetStatus(captor.capture());
    assertNotNull(captor.getAllValues());


}

当我运行测试时,它给了我 NullpointerException在线
        verify(dbMock).addWidgetStatus(captor.capture());

我究竟做错了什么?我查看了几个与 ArgumentCaptor 用法相同的示例。 .也许这只是一个小错误?

最佳答案

如果您使用 MockitoJUnitRunner运行您的测试,然后是 ArgumentCaptor将为您创建,并且无需显式初始化它。如果你这样做,那么你也可以使用 @Mock注释来创建您的模拟对象,也就是说,您不需要 mock不再使用静态方法。您的测试类(class)将像这样开始。

@RunWith(MockitoJUnitRunner.class)
public class WidgetStatusServletTest {

    @Captor private ArgumentCaptor<ArrayList<WidgetStatus>> captor;
    @Mock private DBController mockController;
    @Mock private HttpServletRequest mockRequest;
    @Mock private HttpServletResponse mockResponse;
    @Mock private Repository mockRepository;

This question解决是否使用MockitoJUnitRunner的问题,或显式调用 MockitoAnnotations.initMocks .

只是一个旁注 - 如果您使用变量名称清楚地表明您的对象是模拟的,那么您的测试方法将更容易阅读,就像我在这里所做的那样。否则,在具有许多不同变量的长测试类中,很容易忘记哪些变量引用了模拟,哪些引用了“真实”对象。

关于java - Mockito ArgumentCaptor 在 verify() 上给出 NullpointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23310350/

相关文章:

java - 无法使用 LanguageTool Java API 正确进行拼写检查

java - H2索引名称唯一性

java - 维基百科Tokenizer Lucene

java - 在 MongoDB 和 Apache Solr 之间同步数据的简单方法

java - 将 ArrayList 从 Servlet 传递到 JSP

java - 更新 session 数据的正确语义

java - 如何使用 JSP、Servlet、Hibernate 显示来自 SQL Server 的数据

python - 在单元测试中使用 Flask 作为回调端点?

python - 当我与包 <multiprocessing> 并行运行 test_cases 时,它抛出 ValueError : I/O operation on closed file

unit-testing - 如何在 Android Studio 中分析测试?