Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 使用Moq验证私有方法的执行_Unit Testing_Mocking_Moq_Private Members - Fatal编程技术网

Unit testing 使用Moq验证私有方法的执行

Unit testing 使用Moq验证私有方法的执行,unit-testing,mocking,moq,private-members,Unit Testing,Mocking,Moq,Private Members,我想测试以下逻辑(这显然是我方法的精简版本): 我已经模拟了该方法中的所有其他依赖项,并且我已经设置了这些依赖项,以便能够保证某些条件是真的。我要做的是验证我的privateMethod1()只调用了一次,而privateMethod2()根本没有被调用。这可能与最低起订量有关吗 以下是关于这个问题的一些注意事项: privateMethod1()和privateMethod2()与myPublicMethod在同一个类中,因此我无法为此类创建模拟对象 privateMethod1/2的主体都

我想测试以下逻辑(这显然是我方法的精简版本):

我已经模拟了该方法中的所有其他依赖项,并且我已经设置了这些依赖项,以便能够保证某些条件是真的。我要做的是验证我的privateMethod1()只调用了一次,而privateMethod2()根本没有被调用。这可能与最低起订量有关吗

以下是关于这个问题的一些注意事项:

  • privateMethod1()和privateMethod2()与myPublicMethod在同一个类中,因此我无法为此类创建模拟对象
  • privateMethod1/2的主体都包含来自包含这些和myPublicMethod的类的许多依赖项,因此将privateMethod1/2分解到它们自己的helper类中会非常耗时

有什么想法吗?提前谢谢。我愿意接受这一点,但我想知道这样或那样的方法。

不要测试私有方法。它们是类的私有实现细节。您应该只测试执行公共方法的结果。只要你的结果符合预期,你就不应该在意结果是如何得到的


在私有方法上构建测试将导致脆弱的测试,当您重构私有实现(出于性能或其他原因)时,这些测试很容易中断。

您的类有两个私有实用工具方法,它们封装了一些有用的行为,而您正在测试的公共方法必须使用这种行为。但是,当您进行测试时,您不需要这些方法的正常行为,而是需要替换测试行为。这里有一个典型的依赖性案例。测试时,类内的依赖关系可能会有问题

因此,解决方案与外部依赖的解决方案相同:使用一种或另一种依赖注入将要测试的方法与实现该行为的私有方法断开链接。 例如,可以声明两个私有委托来表示行为:

private Action Behavior1;
private Action Behavior2;
Foo_Accessor testMe = new Foo_Accessor();

bool wasCalled1 = false

testMe.Behavior1 = new Action(() => wasCalled1 = true);

...

Assert.IsTrue(wasCalled1);
在类构造函数中,通常的行为是这样实现的:

public Foo (...)
{
    Behavior1 = privateMethod1;
    Behavior2 = privateMethod2;
...
}
在public方法中,将调用委托而不是实际的方法:

public void myPublicMethod(params) {
    if(some_condition)
        Behavior1();
    else
        Behavior2();
} 
通过这样做,方法之间的绝对依赖性已经消除,因此现在它是可测试的

现在,在测试中,在创建测试对象实例后,您可以覆盖依赖行为:

private Action Behavior1;
private Action Behavior2;
Foo_Accessor testMe = new Foo_Accessor();

bool wasCalled1 = false

testMe.Behavior1 = new Action(() => wasCalled1 = true);

...

Assert.IsTrue(wasCalled1);

我不想测试实际的私有方法;我只是想验证它是被调用的。基本上,我试图遵守一个工作中的策略,它规定每个代码更改都需要一个相应的单元测试(如果单元测试稍后中断,我们就不得不真正考虑什么/为什么我们要做出改变)。我的“代码更改”是导致调用两个私有方法之一的条件逻辑。但是如果你不能从外部测试行为更改,这意味着根本没有真正的更改。如果这是唯一不影响任何结果的实现细节,那么单元测试应该已经涵盖了这一点。单元测试是为了确保像这样的实现更改不会破坏任何东西。您的公司政策可能应该禁止在没有单元测试覆盖的情况下更改功能/行为,而不是在没有添加新的单元测试的情况下。A,您的澄清是有意义的。privateMethod1和privateMethod2基本上是做同一件事的两种不同方式,唯一改变的是它们如何产生相同的结果,但结果本身是不同的。谢谢你和帕特里克的帮助。我不确定这个答案是否有意义。如果