如何对将属性设置为新创建的对象的服务进行单元测试
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())));
}
我想为我的一项服务编写单元测试以验证某些字段是否已分配。
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())));
}