我想为我的一项服务编写单元测试,以验证某些字段是否已分配。
public void createNewRecord(Dto dto) {
Record record = new Record();
record.setName(dto.getName());
record.setDetail(dto.getDetail());
repo.save(record);
}
我没有dto的构造函数,因为记录有许多属性,其中一些属性是从其他方法分配的。我之前的计划是:模拟记录并验证setName()
和setDetail
方法被调用一次。但是没有办法在这项服务中注入模拟记录。我是否必须更改以前的代码?任何想法都表示赞赏。
答案 0 :(得分:1)
有几种方法:
<强>首先强>
将方法改为此
public void createNewRecord(Record record, Dao dao)
<强>第二强>
使用PowerMockito模拟构造函数
<强>第三强>
使用factory或com.google.inject.Provider构建记录(我更喜欢这个)
<强>第四强>
如果记录构造函数很简单,并且记录的setter也没有特殊的逻辑,那么你只能模拟repo并验证repo的参数。
答案 1 :(得分:0)
模拟应该用于模拟测试对象的依赖关系,而不是用于模拟测试方法中的内部对象。 你为什么不模拟repo实例然后你会用mock mock api验证repo.save()是否带有预期的记录? 这似乎是对您的方法进行单元测试的直接方式。
答案 2 :(得分:0)
您可以使用Mockito及其@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())));
}