如何对将属性设置为新创建的对象的服务进行单元测试

How to unit test a service which sets attribute to newly created object

我想为我的一项服务编写单元测试以验证某些字段是否已分配。

public void createNewRecord(Dto dto) {
   Record record = new Record();
   record.setName(dto.getName());
   record.setDetail(dto.getDetail());
   repo.save(record);
}

我没有 dto 的构造函数,因为记录有很多属性,其中一些是从其他方法分配的。我之前的计划是:模拟记录并验证 setName()setDetail 方法被调用一次。但是没有办法将模拟记录注入到该服务中。我必须更改以前的代码吗?任何想法表示赞赏。

有几种方法:

第一个:

将方法更改为此

public void createNewRecord(Record record, Dao dao)

第二个:

使用 PowerMockito 模拟构造函数

第三个:

使用工厂或 com.google.inject.Provider 构造记录(我更喜欢这个)

第四:

如果记录构造函数很简单并且记录的设置器也没有一些特殊的逻辑,那么您可以只模拟 repo 并验证 repo 的参数。

模拟应该用于模拟被测对象的依赖,而不是用于模拟被测方法中的内部对象。 你为什么不模拟回购实例然后你会用你模拟 api 验证 repo.save() 是用预期的记录调用的? 这似乎是对您的方法进行单元测试的直接方法。

您可以使用 Mockito and its @Captor 注释来捕获传递给 repo 实例的参数。您可以 @Mock Dto 对象来创建对 getName()getDetail() 方法的期望,并断言调用 setName()setDetail() 的结果捕获的 Record 实例上的方法与 Dto 对象的预期值相同。例如:

@Mock
private Repo repo;

@Mock
private Dto dto;

@Captor
private ArgumentCaptor<Record> recordArgumentCaptor;

private Service service;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
    this.service = new Service(repo);
}

@Test
public void shouldCreateNewRecord() {
    when(dto.getName()).thenReturn("NAME");
    when(dto.getDetail()).thenReturn("DETAIL");

    service.createNewRecord(dto);

    verify(repo).save(recordArgumentCaptor.capture());
    Record record = recordArgumentCaptor.getValue();

    assertThat(record.getName(), is(equalTo(dto.getName())));
    assertThat(record.getDetail(), is(equalTo(dto.getDetail())));
}