当前位置: 首页 > 面试题库 >

用PHPUnit模拟私有方法

文英达
2023-03-14
问题内容

我有一个关于使用PHPUnit模拟类中的私有方法的问题。让我举一个例子:

class A {
  public function b() { 
    // some code
    $this->c(); 
    // some more code
  }

  private function c(){ 
    // some code
  }
}

我该如何对私有方法的结果进行存根测试以测试公共函数的 更多代码 部分。


问题答案:

通常,您只是不直接测试或嘲笑私有和受保护的方法。

您要测试的是您的类的 公共 API。其他所有内容都是您的类的实现细节,并且如果更改它,则不应“破坏”您的测试。

当您发现“无法获得100%的代码覆盖率”时,这也对您有所帮助,因为您的类中可能包含无法通过调用公共API执行的代码。

但是,如果您的课程如下所示:

class a {

    public function b() {
        return 5 + $this->c();
    }

    private function c() {
        return mt_rand(1,3);
    }
}

我可以看到需要模拟c()的需求,因为“随机”函数是全局状态,您无法对其进行测试。

“干净” /“冗长” //可能过于复杂//“通常”

class a {

    public function __construct(RandomGenerator $foo) {
        $this->foo = $foo;
    }

    public function b() {
        return 5 + $this->c();
    }

    private function c() {
        return $this->foo->rand(1,3);
    }
}

现在,不再需要模拟“ c()”,因为它不包含任何全局变量,并且可以很好地进行测试。

如果您不想执行或无法从私有函数中删除全局状态(不好的事情,坏现实,或者您对坏的定义可能有所不同),则 可以 对模拟 进行 测试。

// maybe set the function protected for this to work
$testMe = $this->getMock("a", array("c"));
$testMe->expects($this->once())->method("c")->will($this->returnValue(123123));

并针对此模拟运行测试,因为您取出/模拟的唯一函数是“ c()”。

引用“实用单元测试”这本书:

“总的来说,您不想为了测试而破坏任何封装(或者就像妈妈曾经说过的那样,“不要公开您的私人信息!”)。大多数时候,您应该能够测试一门课程通过行使其公开方法。如果在私有访问或受保护的访问后面隐藏着重要的功能,则可能是一个警告信号,表明其中还有另一个类别正在努力摆脱困境。”



 类似资料:
  • 我正在尝试测试下一种方法: 称为PrivateMethod: asyncTask的执行无法在Mockito的测试中完成,所以我需要以某种方式模拟它。我试着用PowerMock来嘲弄私有方法: 这在PowerMockito行(NullPointerException)中给了我一个异常,它说 方法引发了“org.mockito.exceptions.Misusing.UnfinishedStubbin

  • 我试图模拟一个私有方法(executeGetRequest),在我声明要为私有方法返回的模拟的那一行中,私有方法实际上是用null参数执行的,因此抛出了一个NullPointerException。 VlcPlayerMinimal。爪哇: VlcPlayerMinimalTest。爪哇: 堆栈跟踪: 它似乎PowerMockito实际上是调用的方法,我试图在行PowerMockito.do返回(

  • 我有一门课看起来像这样: 我想使用Mockito和Powermock为此编写一个单元测试。我知道我可以这样模仿私有方法: 但是我如何告诉它抛出异常呢?我知道会是这样的: 那里有什么? 请注意,异常是一个私有内部类,因此我不能只执行,因为从单元测试中无法访问。

  • 克拉斯托斯特。publicMethod-->classtotest.privateMethod(不是mocking)-->classtoinject.publicMethod1(想要mock) 类如下所示

  • 有人能帮帮我吗?提前谢了。