在Java中使用Mockito模拟JPA存储库不会被调用

在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

我正在为一个使用JPA repo-MessageRepository的服务实现编写单元测试,当我尝试验证是否调用它时,它返回一个“想要但未调用:实际上,与这个模拟没有任何交互”。我提取了部分代码以简化问题解释

服务实施:

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也没有什么区别,仍然失败。我已经做了更改,仍然是相同的结果。我想我不明白你指的是什么。我又添加了一件你需要删除的东西。测试仍然会失败,并出现完全相同的错误。似乎不明白为什么。发布一个完整的复制品,我们只需要复制和粘贴您的代码。当我这么做的时候,你的测试通过了。所以有些事我们不知道。