Php 软断言和模拟方法测试失败

Php 软断言和模拟方法测试失败,php,unit-testing,testing,phpunit,Php,Unit Testing,Testing,Phpunit,我正在学习这个教程:。这是一个学习PHPUnit如何工作的好教程 但是我不能理解,因为考试没有通过 失败是: Method was expected to be called 1 times, actually called 0 times. 在代码的这一部分: $badCode->expects($this->once()) ->method('checkPassword') ->with($passwo

我正在学习这个教程:。这是一个学习PHPUnit如何工作的好教程

但是我不能理解,因为考试没有通过

失败是:

Method was expected to be called 1 times, actually called 0 times.
在代码的这一部分:

        $badCode->expects($this->once())
            ->method('checkPassword')
            ->with($password);
但这是不可能的,因为下一个软断言在checkPassword方法内部运行并通过测试

        $badCode->expects($this->once())
            ->method('callExit');
它之所以失败,是因为它是一个模拟方法,并且行为不同?还是代码错了

为了便于理解,我附上了所有的文件,这是一个小例子

控制台

PHPUnit 3.7.18 by Sebastian Bergmann.

FYOU SHALL NOT PASS............

Time: 0 seconds, Memory: 6.00Mb

There was 1 failure:

1) phpUnitTutorial\Test\BadCodeTest::testAuthorizeExitsWhenPasswordNotSet
Expectation failed for method name is equal to <string:checkPassword> when invoked 1 time(s).
Method was expected to be called 1 times, actually called 0 times.


FAILURES!
Tests: 13, Assertions: 14, Failures: 1.
塞巴斯蒂安·伯格曼的《PHPUnit 3.7.18》。 FYOU不得通过。。。。。。。。。。。。 时间:0秒,内存:6.00Mb 有1次失败: 1) phpUnitTutorial\Test\BadCodeTest::testAuthorizeExitsWhenPasswordNotSet 调用1次时,方法名称等于的预期失败。 方法应被调用1次,实际调用0次。 失败! 测试:13次,断言:14次,失败:1次。 BadCode.php

<?php

namespace phpUnitTutorial;

class BadCode
{
    protected $user;

    public function __construct(array $user)
    {
        $this->user = $user;
    }

    public function authorize($password)
    {
        if ($this->checkPassword($password)) {
            return true;
        }

        return false;
    }

    protected function checkPassword($password)
    {
        if (empty($user['password']) || $user['password'] !== $password) {
            echo 'YOU SHALL NOT PASS';
            $this->callExit();
        }

        return true;
    }

    protected function callExit()
    {
        exit;
    }
}
<?php

namespace phpUnitTutorial;

class BadCode
{
    protected $user;

    public function __construct(array $user)
    {
        $this->user = $user;
    }

    public function authorize($password)
    {
        if ($this->checkPassword($password)) {
            return true;
        }

        return false;
    }

    protected function checkPassword($password)
    {
        if (empty($this->user['password']) || $this->user['password'] !== $password) {
            echo 'YOU SHALL NOT PASS';
            $this->callExit();
        }

        return true;
    }

    protected function callExit()
    {
        exit;
    }
}

您在
setMethods
中缺少一个方法:

->setMethods(array('callExit'))

如果你想检查密码是否被调用,你也需要添加
checkPassword

此处作者-我伪造了该部分,而AppFog(我的主机)的免费帐户(我的)有问题,因此我现在无法更新它


另外,是的,在
checkPassword()

中应该是
$this->user
,我也这么认为(这可能是正确的),但是这个例子仍然不起作用。这个例子是为了了解mock和stub方法之间的区别。在本例中,checkPassword不是int-setMethods,因为它是一个模拟方法,而callExit是一个存根Method@Sangar82是的,你说得对。我已经学会了。。。谢谢你的指导。现在我理解了你的代码,看起来还可以。您需要
callExit()
作为存根,否则它将结束testsuite(使用exit)。将需要更深入的测试。您使用的是哪个PHPUnit版本?但是你应该知道一件事(尽管)它并不直接属于这个问题:使用
$this->user
而不是
checkPassword()中的
$user
@hek2mgl我正在使用3.7.18。类名是错误的代码,不期望更多关于示例的信息,但是很好地解释了存根方法和模拟方法之间的区别。如果移除这些管线,则测试通过。这似乎都是正确的,但没有通过测试,这让我很好奇,我等待解决方案!谢谢你!嘿@Sangar82代码已经更新了。抱歉造成混乱!您已使用($password)删除了$badCode->expects($this->once())->method('checkPassword')->;但是为什么呢?这似乎应该是可行的,但我不明白,因为在删除之前测试失败了lines@Sangar82我犯了一个错误,忘记了您不能对mock方法进行任何断言,只有存根。不过,我认为允许在mock上使用一些
->expects()
会非常有帮助。感谢您的回复,我希望您能够阅读单元测试教程。干得好!
<?php

namespace phpUnitTutorial\Test;

class BadCodeTest extends \PHPUnit_Framework_TestCase
{
    public function testAuthorizeExitsWhenPasswordNotSet()
    {
        $user = array('username' => 'jtreminio');
        $password = 'foo';

        $badCode = $this->getMockBuilder('phpUnitTutorial\BadCode')
            ->setConstructorArgs(array($user))
            ->setMethods(array('callExit'))

        $badCode->expects($this->once())
            ->method('callExit');

        $this->expectOutputString('YOU SHALL NOT PASS');

        $badCode->authorize($password);
    }
}
->setMethods(array('callExit'))