我试图使用Mockito和JUnit来测试服务层,但是每次运行它时,返回对象都会为空。
更多信息:
并测试:
@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;
}
...
答案 0 :(得分:1)
通过findByUserId(UserId)
表示findByUserId(userId)
,
Assert.assertEquals(newUser, user)
是指Assert.assertEquals(result, user)
?值userName和userId从何而来?
请不要使用@InjectMocks注入UserService
尝试以下方法:
@Autowired
private UserService userService;
或至少
@InjectMock
private UserService userService;
您的测试可能会失败,因为UserService内部的存储库无法正确注入,并且返回的结果为 null 。
答案 1 :(得分:1)
除了不正确的模拟用户之外,我还看到一个设计问题。 @InjectMocks
不是一个好的选择。它的实现有缺陷,这是他们的javadocs所说的。
- Mockito将尝试仅通过构造函数注入模拟 注入,*二传手注入或属性注入 如下面所描述的。 *如果以下任何策略失败,则 Mockito 不会报告失败; *即您将拥有 自己提供依赖项。
我认为应该弃用它,以便开发人员可以很好地进行构造函数注入。看看这种方法;
重构UserService
,以便您可以通过UserRepository
的构造函数注入UserService
。
例如:https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-spring-beans-and-dependency-injection.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
}
这是一个好习惯,您可以使用正确的模拟和存根隔离测试您的逻辑(服务,助手等)。
但是,如果您想通过spring ioc容器来验证资源的正确注入并希望执行诸如验证之类的操作,则应该考虑适当的Spring / Spring引导测试。看看官方的Spring测试文档-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html
答案 2 :(得分:0)
您的测试中存在一些问题:
UserService
由Mockito(@InjectMocks
)实例化-请勿使用新的UserService
实例对其进行初始化-这就是获得NPE的原因MockitoJUnitRunner
,因此无需显式调用MockitoAnnotations.initMocks
when(userRepository.findByUserId(UserId))
-什么是UserId
?Mockito.when()
应该是给定部分的一部分