Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Mockito:@InjectMocks(OK)vs模拟对象的构造函数(NPE)_Java_Unit Testing_Nullpointerexception_Mockito - Fatal编程技术网

Java Mockito:@InjectMocks(OK)vs模拟对象的构造函数(NPE)

Java Mockito:@InjectMocks(OK)vs模拟对象的构造函数(NPE),java,unit-testing,nullpointerexception,mockito,Java,Unit Testing,Nullpointerexception,Mockito,以下是应测试的类: public class UserService { private final UserDAO userDAO; private final TransactionManager transactionManager; public UserService(UserDAO userDAO, TransactionManager transactionManager) { this.userDAO = userDAO;

以下是应测试的类:

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));
    }
如果我像下面所示那样将mock注入到被测试的
userService
,这个测试就可以正常工作

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

// no @InjectMocks
UserService userService = new UserService(mockedUserDAO, mockedTransactionManager);
这不应该是同一件事吗?也许我的阅读能力不好,但官方并没有说,
@InjectMocks
应该做一些基本构造函数不具备的特殊功能


你知道为什么传递给构造函数的模拟对象仍然为空吗?

这是从事件顺序来看的:

UserService userService = new UserService(mockedUserDAO, mockedTransactionManager);
创建实例作为创建测试类实例的一部分,但mockito尚未运行,因此
mockedUserDAO
mockedTransactionManager
为空

将实例创建移动到设置方法:

UserService userService;

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

或者
HttpServletRequest mockedReq=mock(HttpServletRequest.class)