[英]Why does my test fail?
我正在开发一个应用程序,在她内部,我必须为UserService类编写测试类。 这是我的服务班级:
private static final Logger LOG = LoggerFactory.getLogger("userLogger");
@EJB
UserDAO userDAO;
@Override
public List<User> list() {
LOG.info("Get all users!");
return Optional.ofNullable(userDAO.findAll())
.orElse(Collections.emptyList()).stream().map(u -> u.toUser())
.collect(Collectors.toList());
}
@Override
public User findById(long id) {
UserEntity userEntity = userDAO.find((id));
if (userEntity == null) {
throw new UserNotFoundException(id);
}
LOG.info("User founded with id {}", id);
return userEntity.toUser();
}
@Override
public User create(User user) {
if (user == null) {
throw new ServiceException("Invalid request!");
}
UserEntity exists = userDAO.find(user.getId());
if (exists != null) {
throw new UserAlreadyExistsException(user.getId());
}
UserEntity userEntity = new UserEntity(user);
userDAO.create(userEntity);
LOG.info("Created user with id {}. Username is {}. Name is {}. Surname is {}. Email is {}.",
userEntity.getUserId(), userEntity.getUsername(), userEntity.getName(),
userEntity.getSurname(), userEntity.getEmail());
return userEntity.toUser();
}
@Override
public User update(long id, User user) {
if (user == null) {
throw new ServiceException("Invalid request!");
}
UserEntity userEntity = userDAO.find((id));
if (userEntity == null) {
throw new UserNotFoundException(id);
}
userEntity.update(user);
userDAO.update(userEntity);
return userEntity.toUser();
}
@Override
public void delete(long id) {
UserEntity userEntity = userDAO.find(id);
if (userEntity == null) {
throw new UserNotFoundException(id);
}
userDAO.delete(userEntity);
LOG.info("Deleted user with id {}", userEntity.getUserId());
}
这是我的测试课:
public class UserServiceImplementationTest {
private static User useric;
@Spy
@InjectMocks
UserService userService;
@Mock
UserDAO userDAO;
@BeforeMethod
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
UserEntity userEntity = mock(UserEntity.class);
willReturn(mock(User.class)).given(userEntity).toUser();
willReturn(userEntity).given(userDAO).find(1L);
useric = new User(7, "DDD", "SDSDS", "SAAsd", "qwqwqw@gmail.com");
}
@Test
public void testWhenUserExist() throws Exception {
// GIVEN
long userId = 0;
// WHEN
User user = userService.findById(userId);
// THEN
assertNotNull(user);
Assert.assertEquals(userId, user.getId());
//verify(userService, Mockito.times(1)).findById(userId);
}
@Test(expectedExceptions = ServiceException.class, expectedExceptionsMessageRegExp = "user-service: User with id: 35 was not found!")
public void testWhenUserNotExist() throws Exception {
// GIVEN
long userId = 35;
// WHEN
userService.findById(userId);
// THEN
fail();
}
@Test
public void testCreateUser() throws Exception{
User user = userService.create(useric);
assertNotNull(user);
Assert.assertEquals(useric.getName(), user.getName());
//User userEntity = new User(1, "aaaewwe", "bbbb", "abba", "asa@gmail.com");
//User user = userService.create(userEntity);
// Assert.assertEquals(user, user);
//assertNotNull(user);
// Assert.assertEquals(userEntity, user);
// verify(userService, Mockito.times(1)).create(userEntity);
}
@Test
public void testDeleteUser() throws Exception{
long userId = 1;
userService.delete(userId);
verify(userService, Mockito.times(1)).delete(userId);
}
}
当我运行此代码时,出现以下错误:
main] INFO userLogger - Created user with id 7. Username is DDD. Name is SAAsd. Surname is SDSDS. Email is qwqwqw@gmail.com.
[main] INFO userLogger - Deleted user with id 0
PASSED: testCreateUser
PASSED: testDeleteUser
PASSED: testWhenUserNotExist
FAILED: testWhenUserExist
com.comtrade.trips.service.user.exception.UserNotFoundException: user-service: User with id: 0 was not found!
at com.comtrade.trips.service.user.UserService.findById(UserService.java:45)
at com.comtrade.trips.service.user.UserServiceImplementationTest.testWhenUserExist(UserServiceImplementationTest.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:104)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:645)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:851)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1177)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
at org.testng.TestRunner.privateRun(TestRunner.java:756)
at org.testng.TestRunner.run(TestRunner.java:610)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:387)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
at org.testng.SuiteRunner.run(SuiteRunner.java:289)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1293)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1218)
at org.testng.TestNG.runSuites(TestNG.java:1133)
at org.testng.TestNG.run(TestNG.java:1104)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:236)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:81)
===============================================
Default test
Tests run: 4, Failures: 1, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 4, Failures: 1, Skips: 0
===============================================
[TestNG] Time taken by org.testng.reporters.JUnitReportReporter@23986957: 21 ms
[TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 13 ms
[TestNG] Time taken by org.testng.reporters.jq.Main@1a04f701: 79 ms
[TestNG] Time taken by org.testng.reporters.XMLReporter@12b0404f: 10 ms
[TestNG] Time taken by org.testng.reporters.EmailableReporter2@7c469c48: 9 ms
[TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@1677d1: 41 ms
我并不傻,我知道该错误意味着什么,但是有人可以说我的测试方法的语法(和逻辑)很好,以及如何为testUserExist方法编写方法吗?
提前致谢
编辑:当我更改了我的测试方法时,我的测试类现在是这样的:
private static User useric;
@Spy
@InjectMocks
UserService userService;
@Mock
UserDAO userDAO;
@BeforeMethod
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
UserEntity userEntity = mock(UserEntity.class);
willReturn(mock(User.class)).given(userEntity).toUser();
//willReturn(userEntity).given(userDAO).find(0L);
//useric = new User(7, "DDD", "SDSDS", "SAAsd", "qwqwqw@gmail.com");
}
@Test
public void testWhenUserExist() throws Exception {
User goran = new User(5, "goran1992", "goran", "palibrk", "palibrk.goran@gmail.com");
User user = userService.create(goran);
// GIVEN
//long userId = 0;
// WHEN
// user = userService.findById(goran.getId());
// THEN
assertNotNull(user);
Assert.assertEquals(user.getId(), goran.getId());
//verify(userService, Mockito.times(1)).findById(userId);
}
@Test(expectedExceptions = ServiceException.class, expectedExceptionsMessageRegExp = "user-service: User with id: 35 was not found!")
public void testWhenUserNotExist() throws Exception {
// GIVEN
long userId = 35;
// WHEN
userService.findById(userId);
// THEN
fail();
}
@Test
public void testCreateUser() throws Exception{
User user = userService.create(useric);
assertNotNull(user);
Assert.assertEquals(useric.getName(), user.getName());
//User userEntity = new User(1, "aaaewwe", "bbbb", "abba", "asa@gmail.com");
//User user = userService.create(userEntity);
// Assert.assertEquals(user, user);
//assertNotNull(user);
// Assert.assertEquals(userEntity, user);
// verify(userService, Mockito.times(1)).create(userEntity);
}
@Test
public void testDeleteUser() throws Exception{
//long userId = 1;
userService.delete(useric.getId());
verify(userService, Mockito.times(1)).delete(useric.getId());
}
而我的控制台给我这个错误:
[main] INFO userLogger - Created user with id 5. Username is goran1992. Name is palibrk. Surname is goran. Email is palibrk.goran@gmail.com.
PASSED: testWhenUserExist
PASSED: testWhenUserNotExist
FAILED: testCreateUser
com.comtrade.trips.common.ServiceException: Invalid request!
at com.comtrade.trips.service.user.UserService.create(UserService.java:54)
at com.comtrade.trips.service.user.UserServiceImplementationTest.testCreateUser(UserServiceImplementationTest.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:104)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:645)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:851)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1177)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
at org.testng.TestRunner.privateRun(TestRunner.java:756)
at org.testng.TestRunner.run(TestRunner.java:610)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:387)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
at org.testng.SuiteRunner.run(SuiteRunner.java:289)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1293)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1218)
at org.testng.TestNG.runSuites(TestNG.java:1133)
at org.testng.TestNG.run(TestNG.java:1104)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:236)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:81)
FAILED: testDeleteUser
java.lang.NullPointerException
at com.comtrade.trips.service.user.UserServiceImplementationTest.testDeleteUser(UserServiceImplementationTest.java:98)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:104)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:645)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:851)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1177)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
at org.testng.TestRunner.privateRun(TestRunner.java:756)
at org.testng.TestRunner.run(TestRunner.java:610)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:387)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
at org.testng.SuiteRunner.run(SuiteRunner.java:289)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1293)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1218)
at org.testng.TestNG.runSuites(TestNG.java:1133)
at org.testng.TestNG.run(TestNG.java:1104)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:236)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:81)
===============================================
Default test
Tests run: 4, Failures: 2, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 4, Failures: 2, Skips: 0
===============================================
[TestNG] Time taken by org.testng.reporters.JUnitReportReporter@2cbb3d47: 22 ms
[TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 28 ms
[TestNG] Time taken by org.testng.reporters.jq.Main@29176cc1: 73 ms
[TestNG] Time taken by org.testng.reporters.XMLReporter@77167fb7: 11 ms
[TestNG] Time taken by org.testng.reporters.EmailableReporter2@18ce0030: 12 ms
[TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@25d250c6: 51 ms
显然,运行test testWhenUserExist()
时, id
1的用户不存在。 如果首先使用此方法创建用户,然后检查该用户是否存在,则该方法应该起作用(并且如果您更改了setUp()
方法,则可以避免产生副作用)。 看起来您在setUp()
方法中创建了id
7的用户。
在您的设置中,您配置
willReturn(userEntity).given(userDAO).find(1L);
因此,您会从userDAO
获得ID为0
的null
您应该更改设置以使用anyLong()
(或与其等效的Easymocks)而不是1L
或将正确的userDAO
配置添加到您的测试方法中:
@Test
public void testWhenUserExist() throws Exception {
// GIVEN
long userId = 0;
willReturn(userEntity).given(userDAO).find(userId);
// WHEN
// ...
}
为什么要模拟和监视被测类?
干净的单元测试应尽可能自然地测试实现,并仅模拟依赖项。
当然,您可以有一些例外,但就您而言,我看不出有任何理由证明测试逻辑不那么直截了当。
在您的情况下,您真正要模拟的一件事是UserService
对UserDAO
的依赖。
剩下的应该是真正和自然的实现。
此外,您还模拟了DAO检索的实体。 测试的逻辑很难理解。
最后,在每个经过测试的方法之前执行的常规setup()会执行很多操作:它已经模拟了某些特定行为。 录制特定的模拟行为应按要求执行。
为了在用户存在时测试findById
方法,我建议您在检索UserEntity时仅模拟UserDAO的行为。
然后,您要检查的是实际用户检索到的与您在模拟记录中提供的匹配项。
这样,您可以检查两件事:
UserEntity
上的UserEntity
toUser()
方法应用于该UserEntity
。 当然,用户应该重写equals()和hashCode(),使该断言有意义:
Assert.assertEquals(actualUser, userEntityByMock.toUser());
或者,您可以按字段检查字段或使用反射。
这是一个片段:
@Mock
private UserDAO userDAOMock;
private UserEntity userEntityByMock;
private UserService service;
@BeforeMethod
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
// You should add a constructor with a arg for that but you could use
// reflection to inject the mock if you don't want to open the api of
// the class
service = UserService(userDAOMock);
userEntityByMock = new UserEntity(1, "DDD", "SDSDS", "SAAsd", "qwqwqw@gmail.com");
}
@Test
public void findByIdWhenTheUserExists() throws Exception {
// GIVEN
long userId = 1;
Mockito.when(userDAOMock.find(userId)).thenReturn(userEntityByMock);
// WHEN
User actualUser = userService.findById(userId);
// THEN
Assert.assertEquals(actualUser, userEntityByMock.toUser());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.