我正在尝试使用junit ockito测试服务层,但是每次运行时,返回对象都会被否定。
更多信息:
- 用户介绍是一个普通的弹簧数据存储库,扩展了crudrepository。
- 用户是一个普通的JPA实体。
和测试:
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService = new UserService();
private User user;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void tesGetUserIdStatus() {
// given
user = new User();
user.setUserName(userName);
user.setUserId(userId);
User newUser = new User();
// when
Mockito.when(userRepository.findByUserId(userId)).thenReturn(newUser);
User result = userService.getUserById(user);
// then
Assert.assertEquals(newUser, user);
}
}
该测试最终将在实际正确时将预期的对象值无效。
我想测试的服务部分如下:
@Component
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User getUserById(User user) throws EntityNotFoundException {
String userId = user.getUserId();
user = userRepository.findByUserId(userId);
return user;
}
...
我还看到了一个设计问题,除了摩知道的不当用户。@InjectMocks
不是一个不错的选择。这是有缺陷的,这是他们的javadocs所说的。
- Mockito将尝试仅通过构造函数注入模拟 注射, *设置器注入或按顺序注入财产注入 如下面所描述的。*如果以下任何策略失败,则 Mockito 不会报告失败;*即你将有 自己提供依赖项。
我认为应该对其进行弃用,以便开发人员可以很好地注入构造函数。看看这种方法;
重构UserService
,因此您可以通过UserService
'S 构造函数注入UserRepository
。例如:https://docs.spring.io/spring-boot/docs/current/referent/reference/html/usis--boot-spring-bean-bean-bean-and-depportency-injoction.html
然后
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
@Mock
private UserRepository userRepository;
private UserService userService;
private User user;
@Before
public void setUp() throws Exception {
userService = new UserService(userRepository);
}
@Test
public void tesGetUserIdStatus() {
//your test code
}
这是一个很好的做法,您可以用正确的模拟和固执孤立地测试逻辑(服务,帮助者等)。
但是,如果要在春季IOC容器中验证正确的资源注入,并且想进行诸如验证之类的操作,则应考虑适当的弹簧/春季启动测试。看看官方春季测试文档-https://docs.spring.io/spring-boot/docs/current/current/referent/html/boot-features-testing.html
findByUserId(UserId)
您的意思是findByUserId(userId)
,并且 Assert.assertEquals(newUser, user)
您是指Assert.assertEquals(result, user)
?值用户名和UserId从何而来?
,请不要使用@InjectMocks注入userService
而是尝试一下:
@Autowired
private UserService userService;
或至少
@InjectMock
private UserService userService;
您的测试可能会失败,因为用户服务中的存储库无法正确注入,并且返回的结果将为 null 。
您的测试中有一些问题:
-
UserService
由Mockito(@InjectMocks
)实例化 - 不要使用新的UserService
实例初始化它 - 这就是您获得NPE
的原因 - 由于您正在使用
MockitoJUnitRunner
,因此您无需明确调用MockitoAnnotations.initMocks
-
when(userRepository.findByUserId(UserId))
-什么是UserId
? - 呼叫
Mockito.when()
应该是给定部分的一部分 - 在当时的部分中,您应该主张您在章节中获得的价值