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)