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

单元测试断言vs Mockito。验证()

从渊
2023-03-14

玩弄Mockito来实现我的服务的单元测试,但由于某种原因,我无法通过我的厚脑袋来实现这一点。我的考试通过了,但我不能确信我做得对。

下面是一个测试count()方法的示例。该方法只是将调用转发到它的存储库,我不想验证仅此而已,没有其他事情发生。这就是我得到的:

@RunWith(MockitoJUnitRunner.class)
public class PersonServiceImplTest {

    @Mock
    private PersonRepository personRepository;

    @InjectMocks
    private PersonServiceImpl personService;

    @Test
    public void testCount() {

        when(personRepository.count()).thenReturn(2L);

        long count = personService.count();

        assertEquals(2L, count);

        verify(personRepository).count();
    }
}

我的考试及格了,但我有一些问题。

>

我需要验证吗?我觉得我这样做是因为我想验证personRepository。实际上调用了count()。或者当我也有assertEquals()时,这是多余的吗?

我是否需要assertEquals和verify?

最后,我做得对吗:)

谢谢你

共有3个答案

马弘益
2023-03-14

最好通过构造函数注入PersonRepository,而不是@InjectMocks。这也消除了对特定运行程序的需要(或者,在稍后的测试中,涉及Spring的低级测试)。

你对Mockito的使用是正确的,但不是最佳的。您确实需要assertEquals,因为您正在测试的是服务返回的值与您从存储库提供的值相同。验证...计数不是必需的,因为它通过检查是否返回了适当的值来暗示。您可以通过返回随机数而不是2来改进这一点。

还要检查是否真的值得在另一个对象中包装count(),或者是否只是添加了不必要的层。

最后,您可以考虑检查Spock;它是JUnit之上的一种基于Groovy的测试语言,提供了一种干净而强大的模拟语言。

司徒墨竹
2023-03-14

整齐:

>

  • 是需要的assertEquals():这取决于。在返回之前,是否对人员服务中的人员Repository.count()的结果进行了任何操作,从而有可能更改其值?如果答案是肯定不是,那么您可能不需要assertEquals()-但是如果有任何可能出错,那么assertEquals()将确保它没有出错。

    是否需要验证():视情况而定。有没有可能personRepository。count()是否未调用?或者它被多次调用(verify()默认情况下期望其参数只被调用一次)?如果没有,那么您可能不需要它。

    你两者都需要吗:这取决于(注意到一种模式?)。见上文:他们做不同的事情。在许多情况下,你希望这两件事都被检查: 1.返回正确的结果,2.通过做你期望做的事情来返回结果。

    你这样做对吗:嗯...看情况。是否人Repository.count()看起来像

    public int count() {
        return this.personService.count();
    }
    

    如果是这样,您可能根本不需要进行太多测试。如果您坚持要进行测试,跳过verify()可能没问题,因为上面的方法除了调用您将要执行的verify函数之外,没有其他方法可以获取值,并且它会返回该值,因此很难多次调用它。

    另一方面,如果函数如下所示:

    public int count() {
        // get a personService from an injector
        // log the personService's details
        // generate a random number
        // try calling count() on personService, catch an error
        // if you caught the error, return the random number
    }
    

    然后,您可能确实想verify(),因为突然之间,发生了很多事情,其中一些事情(即随机数)可能会被混淆,无法正确运行,即使某些事情发生了可怕的错误。

  • 单于正业
    2023-03-14

    是的,你做得对。

    您正在将一个模拟存储库注入到一个真正的服务中,然后测试该服务。当涉及到服务中的业务逻辑时,任何事情都可能发生。这就是为什么用已知的输入和输出验证代码很重要,就像您正在做的那样。

    >

  • 根据存储库的响应,您正在检查业务逻辑的结果。这段代码相当简单,但是想象一下,如果业务逻辑提供的是平均值或总和,而不仅仅是存储库提供的相同值。

    三,。verify和assertEquals正在测试不同的东西。verify检查是否调用了存储库方法,assert检查服务是否使用正确的值响应。假设您的服务方法有一个硬编码的返回2L。assertEquals将通过,但验证将失败。

    是的,你做得对。您测试的内容与您测试的原因有关。是否需要特定的断言或验证通常取决于具体情况。在这种情况下,测试存储库方法是否返回2L,没有什么意义,但测试服务是否返回2L是一个很好的例子。类似地,测试服务方法是否已被调用也没有意义,但测试存储库方法是否已被调用是一个很好的例子。

    现在您有了测试服务的工具,下一步是确定要编写哪些测试。

  •  类似资料:
    • 如果它没有返回任何东西,是否可能以某种方式测试它是否停止了这个if语句?我的意思是,我想把某种断言,检查“好吧,上下文是空的,所以它在这个返回时停止了”。 当然,问题是类是空的,为什么我想测试这种方法可能会有问题,但我想听听一些可能性。

    • 问题内容: 假设我在Python单元测试中具有以下代码: 有没有一种简单的方法可以断言在测试的第二行期间调用了特定方法(在我的情况下)?例如是否有这样的事情: 问题答案: 我为此使用Mock(在py3.3 +上现在是unittest.mock): 对于您的情况,它可能看起来像这样: Mock支持许多有用的功能,包括修补对象或模块的方式以及检查是否调用了正确的东西等。 买者自负! (请当心!) 如果

    • 问题内容: 编辑:切换到一个更好的示例,并阐明了为什么这是一个真正的问题。 我想用Python编写在断言失败时继续执行的单元测试,这样我就可以在一个测试中看到多个失败。例如: 在这里,测试的目的是确保Car’s正确设置其字段。我可以将其分解为四个方法(这通常是个好主意),但是在这种情况下,我认为将其保留为测试单个概念的单个方法(“对象已正确初始化”)更容易理解。 如果我们认为最好不要破坏该方法,那

    • 问题内容: 我有一个Python 2.7方法,有时会调用 当满足正确的条件时,是否可以进行单元测试以验证是否调用了此代码行? 问题答案: 是。加注,因此您可以使用以下命令进行检查: 的实例具有设置为建议的退出状态的属性,并且返回的上下文管理器将捕获的异常实例设置为,因此检查退出状态很容易: sys.exit文档: 从Python退出。这是通过引发异常来实现的…可以在外部级别拦截出口尝试。

    • 我对SonarQube有问题,我的几个单元测试都有问题,引发了以下问题: 为此测试用例添加至少一个断言。 每个测试用例都类似于此格式(其中许多断言被委托给具有公共断言的方法,以避免重复): 现在,很明显,我可以从私有方法中提取这三个断言,并将它们放在测试方法中,但我正在多次执行相同的检查(在不同的字段上)。 所以,我想我会尝试通过(重新)抛出来模拟断言方法的行为: 不幸的是,这种方法也不起作用。

    • 我是单元测试新手,我只是想知道如果一个方法在内部调用自己的公共方法来计算返回值,会怎么样,如下所示: 我正在为它编写单元测试,我的问题是:我应该使用特定的整数值来匹配结果和期望值吗