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

时间:2016-07-15 14:24:32

标签: spring unit-testing junit spring-test

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

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

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

3 个答案:

答案 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())));
}