当前位置: 首页 > 知识库问答 >
问题:

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

朱宜
2023-03-14

我正在尝试对服务方法进行单元测试。服务方法调用spring数据存储库方法来获取一些数据。我想模拟这个存储库调用,并自己提供数据。如何做到这一点?在Spring Boot文档之后,当我模拟存储库并在测试代码中直接调用存储库方法时,模拟工作正常。但是,当我调用服务方法时,反过来调用存储库方法,mocking就不起作用了。下面是示例代码:

服务级别:

@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个答案

谭玉泽
2023-03-14

可能存储库标记了@MockedBean注释。如果存储库是模拟的,我不知道Spring是否可以按类型自动连接。您可以定义@Bean方法并返回Mockito。mock(X.class),这应该可以。

但不确定您是否需要spring来对服务方法进行单元测试。一种更轻松的方法是单独使用Mockito及其@InjectMocks注释。

幸鸿轩
2023-03-14

对于Spring Data存储库,您需要指定bean名称。通过类型模拟似乎不起作用,因为存储库在运行时是一个动态代理。

PersonRepository的默认bean名称是“PersonRepository”,因此应该可以:

@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
    }
}
 类似资料:
  • 在我的项目中,我在进行单元测试时遇到了问题。一个问题是,仅仅进行联调就可以更快地编写,并且还可以测试组件是否真正协同工作。单元测试新颖的“算法”之类的似乎要容易得多。单元测试服务类感觉是错误和无用的。 我使用mockito来模拟spring数据存储库(以及DB访问)。问题是,如果我告诉模拟存储库在方法调用getById时返回实体A,它显然会返回实体A,服务也会返回实体A。是的,该服务做了一些额外的

  • 由于一个人在单元测试和模拟之前没有经验,我使用Mockito学习了关于JUnit的初学者教程,并进行了一些实践。 现在,我需要对一些在MySQL数据库上执行基本数据库操作的类方法进行单元测试。我不想对数据库进行真正的更改。 在不访问真实数据库的情况下,是否存在验证类似方法的方法?还是我误解了单元测试和嘲笑的概念?

  • 问题内容: 我刚开始使用Node,现在正在编写一些单元测试。对于前几个函数,我可以正常运行,但是现在我碰到了一个包含其中的函数。我的函数的简化版本如下所示: 我尝试使用基本节点断言测试库进行测试: 由于执行此操作的时间(以及结果)总是不同的,因此它将始终失败。 在Python中,我可以设置模拟类和对象。有没有一种方法可以在Node中解决此问题而无需将moment.utc()作为函数的参数? 问题答

  • 我想对一个组件的功能进行单元测试。因此,我需要一个模拟服务(根据角度测试指南)。 这里是我的测试床: 那么,嘲笑服务价值的正确方法是什么呢? 弗兰克

  • 问题内容: 在Angular中,所有内容似乎都具有陡峭的学习曲线,并且对Angular应用程序进行单元测试绝对不能逃脱这种范例。 当我开始使用TDD和Angular时,我觉得我花了两倍(可能更多)的时间来弄清楚如何测试,甚至花更多的时间来正确地设置测试。但是正如Ben Nadel 在他的博客中所说的那样,角度学习过程存在起伏。他的图表绝对是我在Angular的经历。 但是,随着我在学习Angula

  • A.我们正在使用spring boot Rest Api进行服务调用。我想我们可以将Junit用于单元测试用例。但需要了解JUnit以外的其他合适的工具或框架来模拟spring boot Rest Api()的单元测试。