在Java中使用Mockito模拟JPA存储库不会被调用
我正在为一个使用JPA repo-MessageRepository的服务实现编写单元测试,当我尝试验证是否调用它时,它返回一个“想要但未调用:实际上,与这个模拟没有任何交互”。我提取了部分代码以简化问题解释 服务实施:在Java中使用Mockito模拟JPA存储库不会被调用,java,spring-boot,unit-testing,junit,mockito,Java,Spring Boot,Unit Testing,Junit,Mockito,我正在为一个使用JPA repo-MessageRepository的服务实现编写单元测试,当我尝试验证是否调用它时,它返回一个“想要但未调用:实际上,与这个模拟没有任何交互”。我提取了部分代码以简化问题解释 服务实施: public class MessageServiceImpl { private final MessageRepository messageRepository; public MessageServiceImpl(MessageRepository mess
public class MessageServiceImpl {
private final MessageRepository messageRepository;
public MessageServiceImpl(MessageRepository messageRepository) {
this.messageRepository = messageRepository;
}
public Message create(){
Message result;
//some operations...
Message message = new Message();
message.setId(2L);
message.setName("123231231");
...
result = save(message);
return result;
}
public Message save(Message message){
Message result = messageRepository.save(message); // returns a null when I debug while Testing
return result;
}
}
单元测试类
@RunWith(SpringRunner.class)
public class MessageServiceImplUnitTest {
@Mock
MessageRepository messageRepository;
@Mock
OtherService otherService; // not a jpa repo but uses one in its implementation and works just as expected
@InjectMocks
MessageServiceImpl messageService;
Message message;
@Before
public void setup() {
initMocks(this);
message = new Message();
message.setId(1L);
message.setMessageDirection(MessageDirection.OUT);
}
// Unit Test for create method of MessageServiceImpl which should return a non-null Message Obj
@Test
public void createShouldReturnNotNullMessageObj(){
// mocking save method to return the same Obj that was passed
when(messageRepository.save(any(Message.class))).then(AdditionalAnswers.returnsFirstArg());
Message result = messageService.create();
// This fails and displays "Wanted but not invoked: Actually, there were
// zero interactions with this mock"
verify(messageRepository).save(any(Message.class));
Assert.assertNotNull(result);
}
我不明白为什么其他模拟服务可以按预期工作,但存储库没有被调用。结果,save(Message Message)Obj将消息Obj返回为null 删除
@SpringBootTest(classes=Abc.class)
:这是一个单元测试,而不是集成测试
删除@Autowired
:您正在使用构造函数注入
删除messageService=newmessageserviceinpl(messageRepository)代码>:Mockito注释为您完成了这一操作,并且由于在该指令之后有initMocks()
,messageRepository
在该点上仍然为空
删除RunWith(MockitoJUnitRunner.class)
,因为您正在代码中显式调用initMocks()
您正在对messageService
变量使用@InjectMocks
。并在构造函数本身上初始化它
做其中一个,而不是两个,我想这就是你的问题所在。@InjectMock
初始化对象并为您注入mock。如果这样做并手动初始化对象,结果可能无法预测
连接也已关闭,您正在使用构造函数初始化,但字段上有@Autowired
注释,请将其移动到构造函数
您的类顶部还有SpringBootTest
注释,这对于单元测试来说是不必要的。正在围绕@InjectMocks进行游戏,并在设置中进行操作,以查看这是否可行。保持两者都没有区别。它仍然失败当你修复你的线路,移除@InjectMocks时会发生什么?那是错误的。我的原始代码中没有自动布线。我已经纠正了这些是我能看到的唯一明显的错误。删除@InjectMocks,而不是在setip中手动初始化obj也没有什么区别,仍然失败。我已经做了更改,仍然是相同的结果。我想我不明白你指的是什么。我又添加了一件你需要删除的东西。测试仍然会失败,并出现完全相同的错误。似乎不明白为什么。发布一个完整的复制品,我们只需要复制和粘贴您的代码。当我这么做的时候,你的测试通过了。所以有些事我们不知道。