【问题标题】:Mockito: @InjectMocks (OK) vs constructor of mocked objects (NPE)Mockito:@InjectMocks(OK)与模拟对象的构造函数(NPE)
【发布时间】:2021-03-02 17:45:20
【问题描述】:

这是应该测试的类:

public class UserService {
    private final UserDAO userDAO;
    private final TransactionManager transactionManager;

    public UserService(UserDAO userDAO, TransactionManager transactionManager) {
        this.userDAO = userDAO;
        this.transactionManager = transactionManager;
    }

    public boolean isUserEmailUnique(HttpServletRequest req, Connection connection) {
        User user = transactionManager //---- NPE if no InjectMocks was done -----
                .doInTransaction(connection, (con) ->
                userDAO.getUserByEmail(con, req.getParameter(Attributes.EMAIL)));

        return Objects.isNull(user);
    }

这里是测试类:

@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
    @Mock HttpServletRequest mockedReq;
    @Mock TransactionManager mockedTransactionManager;
    @Mock Connection mockedConnection;
    
    UserService userService; // QUESTION IS ABOUT THAT OBJECT

    @Test
    public void ifSuchUserWasNotFound_ThenEmailIsUnique() {
        doReturn(new User()).when(mockedTransactionManager).doInTransaction(any(Connection.class), any(TransactionOperation.class));
        assertFalse(userService.isUserEmailUnique(mockedReq, mockedConnection));

        doReturn(null).when(mockedTransactionManager).doInTransaction(any(Connection.class), any(TransactionOperation.class));
        assertTrue(userService.isUserEmailUnique(mockedReq, mockedConnection));
    }

如果我将模拟注入到测试的userService 中,如下所示,此测试工作正常。

@InjectMocks UserService userService;

但是如果我创建一个新实例并将模拟对象传递给构造函数,如下所示,一个关于 transactionManager 的 NullPointerException 会在测试类中抛出

// no @InjectMocks
UserService userService = new UserService(mockedUserDAO, mockedTransactionManager);

不应该是一样的吗?也许我是一个糟糕的读者,但官方article 并没有说@InjectMocks 应该做一些基本构造函数不可用的特殊操作。

任何想法为什么传递给构造函数的模拟对象仍然为空?

【问题讨论】:

    标签: java unit-testing nullpointerexception mockito


    【解决方案1】:

    这是从事件的顺序来的:

    UserService userService = new UserService(mockedUserDAO, mockedTransactionManager);
    

    创建实例作为创建测试类实例的一部分,但 mockito 尚未运行,因此 mockedUserDAOmockedTransactionManager 为空。

    将实例创建移至设置方法:

    UserService userService;
    
    @Before
    public void prepareTest() {
        userService = new UserService(mockedUserDAO, mockedTransactionManager);
    }
    

    【讨论】:

    • HttpServletRequest mockedReq = mock(HttpServletRequest.class)
    猜你喜欢
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    相关资源
    最近更新 更多