如何模拟Spring Data和单元测试服务

时间:2016-07-10 16:28:47

标签: spring spring-boot spring-data

我试图对服务方法进行单元测试。服务方法调用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
    }
}

2 个答案:

答案 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注释。