【问题标题】:How to handle objects created within the method under test如何处理在被测方法中创建的对象
【发布时间】:2022-01-20 16:06:12
【问题描述】:

我有以下模型类:

@Data
public class Address {
    private String street;
    private int number;
}
@Data
public class Person {
    private String name;
    private Address address;
}

以及以下服务:

@Service
public class MyService {
  private final OtherService otherService;

  public MyService(OtherService otherService) {
    this.otherService = otherService;
  }

  public void create() {
    Person myPerson = new Person();
    myPerson.setName("John");
    otherService.synchronize(myPerson);
    myPerson.getAddress().setNumber(12);
  }
}
@Service
public class OtherService {
    public void synchronize(Person person) {
        Address address = new Address();
        address.setStreet("sample street");
        address.setNumber(123);
        person.setAddress(address);
    }
}

我想为 MyService 编写一个单元测试。这是测试的无效版本:

@ExtendWith(SpringExtension.class)
class MyServiceTest {
    @Mock OtherService otherService;

    @InjectMocks MyService myService;

    @Test
    void test_create() {
        // GIVEN
        doNothing().when(otherService).synchronize(any(Person.class));

        // WHEN
        myService.create();

        // THEN
        verify(otherService).synchronize(any());
    }
}

这失败了,因为myPerson 对象是在被测试的方法中创建的,因此在运行测试时我得到了NullPointerException。我该如何处理这个问题?我应该捕获传递给 otherService 的值吗?

【问题讨论】:

  • 失败是因为getAddress()create方法中返回null
  • 是的。但这就是我想要处理的。真正的服务不会抛出异常,因为真正的 otherService 会设置地址字段。
  • 所以,如果你想简单验证,synchronize() 方法被调用,Address 仍然不能为空以避免抛出 NPE。你可以使用doAnswer(invocation -> { Person person = invocation.getArgument(0); person.setAddress(new Address()); return null;}).when(otherService).synchronize(any(Person.class));
  • 这是您要找的吗?
  • 是的,感谢您的帮助

标签: spring unit-testing junit mockito


【解决方案1】:

有点复杂,但还不错。将您的 doNothing 调用替换为以下内容:

Mockito.doAnswer(
    new Answer<Void>() {
       public Void answer(InvocationOnMock invocation) throws Exception {
            Person arg = invocation.getArgument(0);
            arg.setAddress(new Address());
            return;
      }
    }).when(otherService).synchronize(any(Person.class));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 2014-04-26
    • 2017-08-12
    • 1970-01-01
    • 2020-01-28
    • 2018-02-07
    相关资源
    最近更新 更多