【问题标题】:JUnit Mockito mock one method in another class ErrorJUnit Mockito 在另一个类错误中模拟一个方法
【发布时间】:2016-06-11 10:10:33
【问题描述】:

我使用 Netbeans 8.1、Junit 和 Mockito 为我的项目编写单元测试。 这是我的一些代码

待测功能:

public Map<String, String> getAllUsers() {

    if (allUsers == null) {
        if (session.checkACL2("DonateBookPrivilegeLevel") || session.checkACL2("ManageUserPrivilegeLevel")) {
            Iterator<User> it = userFc.findAll().iterator();
            System.out.println("PC::enum()");
            allUsers  = new HashMap<String, String>();
            while (it.hasNext()) {
                User item = it.next();
                allUsers.put(item.getName(), item.getUserId().toString());
            }
        }
    }
    return allUsers;
}

我的测试课:

package com.controller;

import com.entities.User;
import com.jsfc.util.JsfUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.faces.event.ActionEvent;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.runner.RunWith;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import org.mockito.Mock;
import org.mockito.Mockito;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;


@RunWith(MockitoJUnitRunner.class)
public class PersonalCenterControllerTest {

    public PersonalCenterControllerTest() {
    }

    @BeforeClass
    public static void setUpClass() {

    }

    @AfterClass
    public static void tearDownClass() {
    }

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

    @After
    public void tearDown() {
    }  

    /**
     * Test of getAllUsers method, of class PersonalCenterController.
     */
    @Test
    public void testGetAllUsers() {
        System.out.println("getAllUsers");

        PersonalCenterController pcController = new PersonalCenterController();

        SessionController session = Mockito.mock(SessionController.class);

        when(session.checkACL2(anyString())).thenReturn(true).thenReturn(true);

        Map<String,String> userMap = null;
        userMap = pcController.getAllUsers();

    } 
}

如您所见,我调用了在另一个类中定义的 session.checkACL2(),我使用Using Mockito to mock a class method inside another class 来修复

SessionController session = Mockito.mock(SessionController.class);
doReturn(true).when(session).checkACL2((String) anyObject());

但它在 if 行调用 NullPointerException

【问题讨论】:

  • 您使用的是哪个 Junit 跑步者?您是否使用 @RunWith(MockitoJUnitRunner.class) 或类似的东西注释了您的课程?你能发布你的完整课程,包括导入语句吗?您可以删除其他不适用的功能。
  • 我使用 Netbeans 集成的 junit 4.12。我之前忘记添加 @RunWith(MockitoJUnitRunner.class) ,但是添加之后,它仍然显示错误:导致错误:java.lang.NullPointerException。当我转到 Source 时,它​​仍然停留在 session.checkACL2()
  • 你不需要 thenReturn 两次。您可以粘贴 NullPointerException 堆栈跟踪吗?
  • 我发现了问题,你可以看看Andrey Bardyshev的回答。 NullPointerException 是因为我没有将我的模拟SessionController 实例设置为PersonalCenterController 实例。谢谢。
  • 您也可以使用 mockStatic,这样 SessionController 的所有实例都将采用您定义的行为,因此您不必将对象传递给您的控制器。但是,显式传递是更好和正确的方法。

标签: unit-testing junit mockito


【解决方案1】:

您实际上是否将模拟的 SessionController 实例传递给您的 PersonalCenterController 实例? 如果您在模拟后立即尝试调用 SessionController 方法,它会返回您所期望的吗?

SessionController session = Mockito.mock(SessionController.class);
when(session.checkACL2(anyString())).thenReturn(true).thenReturn(true);
assertTrue(session.checkACL2("DonateBookPrivilegeLevel"));
assertTrue(session.checkACL2("ManageUserPrivilegeLevel");

正如我所见,NullPointerException 可能来自 session 实例,要么是 null,要么返回 null,然后将其转换为 boolean。我的第一步是弄清楚它是哪一个。

【讨论】:

  • 我发现了这个问题,但是在待测函数中可以看到,session是一个私有成员变量。如果我想将我的模拟会话实例设置为 PersonalCenterController 实例,我必须调用类 setSession() 中的另一个方法,当我测试一个函数时调用另一个函数是否正确?
  • 如果你有一个简单的 setter setSession() 没有额外的行为,那么我认为这很好。如果你在setSession() 中有一些复杂的逻辑,但你已经用其他测试覆盖了这个逻辑,我认为它也很好。
【解决方案2】:

确保您使用“MockitoJUnitRunner.class”运行您的 JUnit。

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest{

public void myMethodTest(){
   SessionController session = Mockito.mock(SessionController.class);
 Mockito.when(session).checkACL2(Mockito.anyString()).thenReturn(true).thenReturn(true);
  //Write logic to test your businesss logic inside class and assert the result.
}

}

【讨论】:

  • 我在我的测试之前添加了 @RunWith(MockitoJUnitRunner.class) 但它仍然显示错误:导致错误:java.lang.NullPointerException。当我转到 Source 时,它​​仍然停留在 session.checkACL2()
猜你喜欢
  • 1970-01-01
  • 2015-10-14
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多