使用 mockito 和 Junit 进行单元测试时如何处理 Page
How to deal with Page while unit testing with mockito and Junit
我想用假数据模拟数据库调用,但我遇到了以下情况:
我的服务
public class MyService {
// some stuff
Page<SampleDto> sample = repo.findAllSample();
// other stuff
}
我想用 when()
存根,但我做不到。我的测试是:
我的服务测试
public class MySampleTest {
@Test
void myTest() {
// initialisation and all stuff
when(myRepo.findAll()).thenReturn(......)
// I want to pass 2 fake SampleDto from
// here but don't know how to do that
}
}
解决此类任务通常有两个主要方向:
- 假对象
- 嘲讽
假对象 方法是在 lightweight/simple 情况下没有任何第三方库的简单实现你的回购:
public class FakeRepo implements Repo<T> {
private final Collection<T> all;
public FakeRepo(){
this(Collections.emptySet());
}
public FakeRepo(Collection<T> all){
this.all = all;
}
@Override
public Collection<T> findAll(){
return this.all;
}
}
在你的测试中可能看起来像
@Test
public void justdoit(){
MyService service = new MyService(
new FakeRepo(Arrays.asList(1,2))
);
// test the service & methods
}
Mocking 允许您制作更复杂的解决方案。
请注意方法 Mockito.mock(ArrayList.class)
和 Mockito.spy(new ArrayList<String>())
。您需要使用 Mockito 引擎 assemble 您的复杂对象,例如
https://www.baeldung.com/mockito-annotations
@Test
public void whenNotUseMockAnnotation_thenCorrect() {
List mockList = Mockito.mock(ArrayList.class);
mockList.add("one");
Mockito.verify(mockList).add("one");
assertEquals(0, mockList.size());
Mockito.when(mockList.size()).thenReturn(100);
assertEquals(100, mockList.size());
}
或
@Test
public void whenNotUseSpyAnnotation_thenCorrect() {
List<String> spyList = Mockito.spy(new ArrayList<String>());
spyList.add("one");
spyList.add("two");
Mockito.verify(spyList).add("one");
Mockito.verify(spyList).add("two");
assertEquals(2, spyList.size());
Mockito.doReturn(100).when(spyList).size();
assertEquals(100, spyList.size());
}
只需创建您想要 returned 的内容并将其传递给 thenReturn()
。
在你的情况下它可能是这样的:
// I making this up, because you did not state what 'Page' actually is
var result = new Page();
result.add(new SampleDto(1));
result.add(new SampleDto(2));
when(myRepo.findAllSample()).thenReturn(result);
您可能无法执行此操作,具体取决于 Page
的实际实现,例如,如果这是一个 JPA Page
。在这种情况下,您不应该真正 return Page
到您的服务中,而是将 JPA 存储库包装到一个 return 是 List<SampleDto>
或 Set<SampleDto>
的适配器存储库中.否则,属于域的服务将依赖于基础结构代码(如 JPA)的实现细节,这很少是一个好主意。
如果需要在您的服务 class 中处理一些其他功能,您也可以模拟 Page
对象。假设您的服务 class 实际上是这样的:
public class MyService {
@Resource
private SampleRepository repo;
public Page<SampleDto> findAllSample() {
var sampleData = repo.findAllSample();
// perhaps some operations with sample data and page
return sampleData;
}
}
那么测试 class 可能类似于 (JUnit4):
@RunWith(MockitoJUnitRunner.class)
public class MySampleTest {
@Mock
private SampleRepository repo;
@Mock
private Page<SampleDto> page;
@InjectMocks
private MyService myService;
@Test
public void test() {
doReturn(page).when(repo).findAll();
var listSampleDtos = List.of(new SampleDto()); // populate with what you need
doReturn(listSampleDtos).when(page).getContent();
var page = myService.findAllSample();
// ... do the asserts, just as an example:
verify(repo).findAll(); // called
assertEquals(1, page.getContent().size());
}
您可以模拟页面并制作示例对象。可能这就是您要搜索的确切答案。
我的样本测试
public class MySampleTest {
@Test
void myTest() {
// initialisation and all stuff
List<SampleDto> sampleDtos = new ArrayList<>();
//now add any number of sample dto
dtos.add(new SampleDto());
//mock page class here
Page page = mock(Page.class);
//stub page.getContent
when(page.getContent()).thenReturn(Collections.singletonList(sampleDtos));
// No need to do this when(myRepo.findAll()).thenReturn()
}
}
我想用假数据模拟数据库调用,但我遇到了以下情况:
我的服务
public class MyService {
// some stuff
Page<SampleDto> sample = repo.findAllSample();
// other stuff
}
我想用 when()
存根,但我做不到。我的测试是:
我的服务测试
public class MySampleTest {
@Test
void myTest() {
// initialisation and all stuff
when(myRepo.findAll()).thenReturn(......)
// I want to pass 2 fake SampleDto from
// here but don't know how to do that
}
}
解决此类任务通常有两个主要方向:
- 假对象
- 嘲讽
假对象 方法是在 lightweight/simple 情况下没有任何第三方库的简单实现你的回购:
public class FakeRepo implements Repo<T> {
private final Collection<T> all;
public FakeRepo(){
this(Collections.emptySet());
}
public FakeRepo(Collection<T> all){
this.all = all;
}
@Override
public Collection<T> findAll(){
return this.all;
}
}
在你的测试中可能看起来像
@Test
public void justdoit(){
MyService service = new MyService(
new FakeRepo(Arrays.asList(1,2))
);
// test the service & methods
}
Mocking 允许您制作更复杂的解决方案。
请注意方法 Mockito.mock(ArrayList.class)
和 Mockito.spy(new ArrayList<String>())
。您需要使用 Mockito 引擎 assemble 您的复杂对象,例如
https://www.baeldung.com/mockito-annotations
@Test
public void whenNotUseMockAnnotation_thenCorrect() {
List mockList = Mockito.mock(ArrayList.class);
mockList.add("one");
Mockito.verify(mockList).add("one");
assertEquals(0, mockList.size());
Mockito.when(mockList.size()).thenReturn(100);
assertEquals(100, mockList.size());
}
或
@Test
public void whenNotUseSpyAnnotation_thenCorrect() {
List<String> spyList = Mockito.spy(new ArrayList<String>());
spyList.add("one");
spyList.add("two");
Mockito.verify(spyList).add("one");
Mockito.verify(spyList).add("two");
assertEquals(2, spyList.size());
Mockito.doReturn(100).when(spyList).size();
assertEquals(100, spyList.size());
}
只需创建您想要 returned 的内容并将其传递给 thenReturn()
。
在你的情况下它可能是这样的:
// I making this up, because you did not state what 'Page' actually is
var result = new Page();
result.add(new SampleDto(1));
result.add(new SampleDto(2));
when(myRepo.findAllSample()).thenReturn(result);
您可能无法执行此操作,具体取决于 Page
的实际实现,例如,如果这是一个 JPA Page
。在这种情况下,您不应该真正 return Page
到您的服务中,而是将 JPA 存储库包装到一个 return 是 List<SampleDto>
或 Set<SampleDto>
的适配器存储库中.否则,属于域的服务将依赖于基础结构代码(如 JPA)的实现细节,这很少是一个好主意。
如果需要在您的服务 class 中处理一些其他功能,您也可以模拟 Page
对象。假设您的服务 class 实际上是这样的:
public class MyService {
@Resource
private SampleRepository repo;
public Page<SampleDto> findAllSample() {
var sampleData = repo.findAllSample();
// perhaps some operations with sample data and page
return sampleData;
}
}
那么测试 class 可能类似于 (JUnit4):
@RunWith(MockitoJUnitRunner.class)
public class MySampleTest {
@Mock
private SampleRepository repo;
@Mock
private Page<SampleDto> page;
@InjectMocks
private MyService myService;
@Test
public void test() {
doReturn(page).when(repo).findAll();
var listSampleDtos = List.of(new SampleDto()); // populate with what you need
doReturn(listSampleDtos).when(page).getContent();
var page = myService.findAllSample();
// ... do the asserts, just as an example:
verify(repo).findAll(); // called
assertEquals(1, page.getContent().size());
}
您可以模拟页面并制作示例对象。可能这就是您要搜索的确切答案。
我的样本测试
public class MySampleTest {
@Test
void myTest() {
// initialisation and all stuff
List<SampleDto> sampleDtos = new ArrayList<>();
//now add any number of sample dto
dtos.add(new SampleDto());
//mock page class here
Page page = mock(Page.class);
//stub page.getContent
when(page.getContent()).thenReturn(Collections.singletonList(sampleDtos));
// No need to do this when(myRepo.findAll()).thenReturn()
}
}