【问题标题】:Create test for service method that saves an object and returns long value为保存对象并返回长值的服务方法创建测试
【发布时间】:2023-02-22 18:01:58
【问题描述】:

我正在尝试测试一种服务方法。该方法接收信息,使用该信息创建对象。比它保存这个对象。比它返回该对象的 ID。

当我尝试对此进行测试时,我的测试一直失败,并指出返回的对象为空。我想知道如何测试这个。在这 我正在尝试使用返回 1L 的 getId() 来模拟生成的对象。比我让保存方法返回模拟对象。这似乎也行不通。

我真的可以使用一些帮助我应该如何正确地测试这个方法。

示例方法:

public long addNotification(ObjectWithInformation objectWithInformation){
       NewObject newObject = // retrieve information based on objectWithInformation
       repository.save(newObject);
       repository.flush();
       return newObject.getId();

}

我目前如何尝试测试(测试编译,getId() 仍然返回 nullvalue):

@Test
void addNotification(){
     NewObject newObjectmock = mock(NewObject.class);
     Mockito.when(newObjectmock.getId()).thenReturn(1L);
     when(repository.save(Mockito.any(NewObject.class))).thenReturn(newObjectmock);

     service.addNotification(ObjectWithInformation objectWithInformation);

     //verify methods, which I cannot reach due to getId() returning null in the service method.

}

【问题讨论】:

  • 您遗漏了示例方法中最重要的部分:// retrieve information based on objectWithInformation 中到底发生了什么??在测试中,您没有将与模拟对象相关的任何内容放入 objectWithInformation 中,那么您的方法 addNotification 将如何获得该模拟?它是否使用 new 运算符创建 newObject

标签: java testing junit mockito


【解决方案1】:

您不能对函数内部生成的对象执行测试,也不能提前模拟它。这只能通过接受对象作为参数并返回这些对象的函数来实现。

你的模拟是正确的,但 junit 无法训练函数内的 newobject 返回 id。所以你必须训练你的存储库返回一个带有 id 的模拟对象(这是你做对的)。您的函数有一个中间步骤,您传递经过训练的方法并返回空值,因为 newObject 没有 id 值。您必须立即在函数中返回 id。

还使用 saveAndFlush 代替 save() 和 flush()。两者都可以工作,但第一个更干净并且更适合测试。

这将使它工作:


when(repository.saveAndFlush(Mockito.any(NewObject.class))).thenReturn(newObjectmock);

public long addNotification(ObjectWithInformation objectWithInformation){
       NewObject newObject = // retrieve information based on objectWithInformation
       return repository.saveAndFlush(newObject).getId();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多