我试图对服务方法进行单元测试。服务方法调用spring数据存储库方法来获取一些数据。我想模拟该存储库调用,并自己提供数据。怎么做?在Spring Boot documentation之后,当我模拟存储库并直接在我的测试代码中调用存储库方法时,模拟工作正常。但是当我调用服务方法时,反过来会调用存储库方法,模拟不起作用。以下是示例代码:
服务类:
@Service
public class PersonService {
private final PersonRepository personRepository;
@Autowired
public PersonService(personRepository personRepository) {
this.personRepository = personRepository;
}
public List<Person> findByName(String name) {
return personRepository.findByName(name); // I'd like to mock this call
}
}
测试类:
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
// http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-testing-spring-boot-applications-mocking-beans
@MockBean
private PersonRepository personRepository;
@Autowired
private PersonService personService;
private List<Person> people = new ArrayList<>();
@Test
public void contextLoads() throws Exception {
people.add(new Person());
people.add(new Person());
given(this.personRepository.findByName("Sanjay Patel")).willReturn(people);
assertTrue(personService.findByName("Sanjay Patel") == 2); // fails
}
}
答案 0 :(得分:4)
对于Spring Data存储库,您需要指定bean名称。通过类型进行模拟似乎不起作用,因为存储库在运行时是动态代理。
PersonRepository
的默认bean名称是&#34; personRepository&#34;,所以这应该有效:
@MockBean("personRepository")
private PersonRepository personRepository;
这是完整的测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
// http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-testing-spring-boot-applications-mocking-beans
@MockBean("personRepository")
private PersonRepository personRepository;
@Autowired
private PersonService personService;
private List<Person> people = new ArrayList<>();
@Test
public void contextLoads() throws Exception {
people.add(new Person());
people.add(new Person());
given(this.personRepository.findByName("Sanjay Patel")).willReturn(people);
assertTrue(personService.findByName("Sanjay Patel") == 2); // fails
}
}
答案 1 :(得分:1)
可能存储库标有@MockedBean批注。如果存储库是模拟的,我不知道Spring是否可以按类型自动连接。 你可以定义@Bean方法并返回Mockito.mock(X.class),这应该可行。
不确定您是否需要弹簧来进行单元测试服务方法。一种较轻的方法是单独使用Mockito及其@InjectMocks注释。