【发布时间】:2018-07-26 07:06:13
【问题描述】:
我正在尝试了解如何在 Spring 项目中使用 Mockito,但我对以下问题有些困惑:
我即将使用真实的(内存中)存储库测试服务。我正在嘲笑该服务正在使用的所有其他对象。如果我理解正确,使用@Mock 注释对象将被嘲笑,@Spy 将使用真实对象,而@InjectMocks 将“自动装配”这些注释对象。但是,我想我误解了@Spy,因为以下代码不起作用(似乎插入了一个模拟对象,既没有数据库交互,也没有出现NullPointerException):
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserServiceTests {
@Spy
@Autowired
private UserRepository userRepository;
@Mock
private MessageService messageService;
@InjectMocks
private UserService userService = new UserServiceImpl();
@Test
public void testUserRegistration() {
userService.registerUser("test@test.test");
Assert.assertEquals("There is one user in the repository after the first registration.", 1, userRepository.count());
}
}
如果我删除 @Spy 注释并使用反射将存储库插入服务中,它可以工作:
ReflectionTestUtils.setField(userService, "userRepository", userRepository);
这似乎很不方便,我很确定@Spy 就是为了这样做。谁能指出我遗漏/误解的内容?
编辑:还有一件事 - 使用 @Spy 注释我在保存时没有得到 NullPointerException,但似乎插入了一个模拟对象而不是真正的存储库。
编辑 2: 我认为这是我困惑的答案:
【问题讨论】:
-
为什么你有 Autowired 和 Spy?你能扩展一下“不工作”吗?
-
很确定您应该在您的存储库上方使用
@Mock -
如果可行的话,最好使用构造函数注入正是因为这个原因——你不需要 Spring 进行这个测试,可以简单地创建一个模拟并将其传递给
new UserServiceImpl(mockUserRepository)。 -
@chrylis 这意味着我必须修改所有服务,因为到处都在使用字段注入,我想避免这种情况。
-
@ThomasWithers 我正在尝试使用内存数据库进行测试,Mock 不会做我想要的,对吗?
标签: java spring testing mockito