java - 将存储库的模拟注入服务不会注入正确的模拟方法(Spring、JUnit 和 Mockito)
问题描述
tl;dr:似乎我使用自定义行为创建的存储库的 Mock 关于注入时保存方法的自定义行为丢失了自定义行为。
问题描述
我一直在尝试在 Spring 中测试服务。特别感兴趣的方法采用一些参数并创建一个用户,该用户通过存储库方法save保存到UserRepository中。
我感兴趣的测试是将这些参数与传递给存储库的保存方法的用户属性进行比较,并以这种方式检查它是否正确添加了新用户。
为此,我决定模拟存储库并将相关服务方法传递的参数保存到存储库保存方法。
我基于这个问题来保存User。
private static User savedUser;
public UserRepository createMockRepo() {
UserRepository mockRepo = mock(UserRepository.class);
try {
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
savedUser= (User) invocation.getArguments(0);
return null;
}
}).when(mockRepo).save(any(User.class));
} catch( Exception e) {}
return mockRepo;
}
private UserRepository repo = createMockRepo();
两个注意事项:
我给出了名称 repo,以防名称必须与服务中的名称匹配。
没有@Mock注释,因为它开始未能通过测试,我认为这是因为它将以通常的方式创建一个模拟(没有我之前创建的自定义方法)。
然后我创建了一个测试函数来检查它是否具有所需的行为并且一切都很好。
@Test
void testRepo() {
User u = new User();
repo.save(u);
assertSame(u, savedUser);
}
然后,我尝试按照我在多个问题中看到的建议进行操作,即将模拟注入到服务中,如此处所述。
@InjectMocks
private UserService service = new UserService();
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
这就是问题出现的地方,当我尝试访问savedUser属性时,我为它创建的测试抛出了一个空异常(这里我简化了 users 属性,因为这似乎不是原因)。
@Test
void testUser() {
String name = "Steve";
String food = "Apple";
service.newUser(name, food);
assertEquals(savedUser.getName(), name);
assertEquals(savedUser.getFood(), food);
}
调试时:
- 该服务似乎已收到模拟:已调试服务的属性
- savedUser确实为null:调试的savedUser 属性。
出于演示目的,我决定使用System.out.println记录该函数。
我在这里做错了什么?
提前感谢您的帮助,这是我的第一个堆栈交换问题,非常感谢任何改进提示。
解决方案
不要像您那样在测试类中实例化您的服务,而是使用 @Autowired 并确保您的 UserRepository 在测试类中有 @MockBean
@InjectMocks
@Autowired
private UserService service
@MockBean
private UserRepository mockUserRepo
有了这个,你可以删除你的设置方法
但请确保您的 UserRepository 也在您的服务内部自动装配
推荐阅读
- sql - SQL Server:将参数布尔值从 vb net 添加到 sql 作为位
- mysql - 如何在 php7 中更改旧版本的 php 工作
- javascript - 如何从回调函数函数中获取位置(结果)
- python - KIVY : BoxLayout 包含水平 BoxLayout
- python-3.x - 如何使用python中的嵌套循环从列表中打印指定次数的所有字符串
- python - Docker CLI 允许标记,但 Docker Python API 引发 APIError
- python - PyCharm | 函数 myFunction 位于 0x000001EBF0C97B70
- c# - 创建后更改 GameWindow 的 GraphicsMode
- reactjs - 无法在反应中更新状态
- reactjs - 使用 React 将表单发布到 API