JUnit 测试对象在进程中如何更改以及最终断言

JUnit to test how object changes mid process along with final assertions

提问人:Jay C 提问时间:9/22/2023 最后编辑:NicolasJay C 更新时间:9/24/2023 访问量:35

问:

我有一个由多个进程使用的私有方法,我正在为一个公共方法编写单元测试,在 pitest 期间,删除对一行的调用的突变仍然存在,因此为了修复它(不告诉测试忽略该突变)我想检查对象是否在进程中间更新了某个值,在进程结束时更新了另一个值。可能吗?

public class MyClass {

    public List<Mango> publicMethod() {
    List<Mango> mangos = apiCall();
        privateMethod1(mangos);
        privateMethod2(mangos);
        return mangos;
    }

    private void privateMethod1(List<Mango> mangos) {
        mangos.forEach(mango -> {
            if(mango.getName("indigenous") {
                mango.setAmount(100);
                mango.setQuantity(10);
            }
        });
    }

     private void privateMethod2(List<Mango> mangos) {
        mangos.forEach(mango -> {
            if(mango.getName("indigenous") {
                mango.setAmount(50);
            }
        }
    });   
}

在 publicMethod() 的单元测试中,删除了对 mango.setAmount(100) 的调用;当它在 privateMethod2 中再次更新时会继续存在,但 privateMethod1 被多个进程使用,因此不应更新。在实际情况下,这些方法中发生了多种事情,但为了解释问题,我使用简单的 set 方法到一个对象。代替 mango.setAmount(100);在实际代码中,有一个私有方法,它将更新对象的某些值。

为了使 pitest 不忽略该行,我尝试使用 Mockito.verify() 来检查私有方法是否被调用了两次,但 mokito 不允许我们验证私有方法。

java spring-boot junit mockito pitest

评论

0赞 Nicolas 9/22/2023
如果我理解正确的话,你是在尝试测试行为,而不影响结果吗?privateMethod1()privateMethod2()
0赞 Jay C 9/22/2023
我想验证mango.setAmount(100)发生在mango.setAmount(50)之前。我能够断言金额 50,因为它存在于输出中,而不是金额 100。
0赞 Nicolas 9/22/2023
你的单元测试不应该担心公共方法是如何做他们的事的。他们应该只关注这些方法的输入和输出。知道了这一点,就很难创建一个只断言方法一部分的测试。但是,您可以做的是使用模拟并断言被调用两次,并断言参数。我已经很久没有做过 Java 了,所以我不能给你一个具体的例子,但你可以看看这个答案以获取更多信息 stackoverflow.com/a/57281503/5784924setAmount

答:

0赞 Gabriela83 9/24/2023 #1
  1. 您不应该关心私有方法的行为,因为单元测试只关注公共方法的输入/输出。

  2. 如果你真的需要实现这一点,你可以尝试创建一个对象()的间谍,并检查setter是否被你预期地调用了: 以及MangoMango mango = Mockito.spy(Mango.class)verify(mango).setAmount(100)verify(mango).setAmount(50)