PHP单元测试和Mockery模拟

时间:2013-05-30 16:46:45

标签: php unit-testing phpunit mockery

这可能是我嘲笑的一个误解。我真的很感激为什么嘲笑一个不存在的或现存的类是一件好事?

示例场景:假设我们有一个类依赖于第二个类的输出,我们更改输出格式或其他。这会不会让我们的测试成功,尽管他们在第一堂课中已经过时了?

2 个答案:

答案 0 :(得分:4)

答案是肯定的!如果您尊重代码中的某些可测试性原则,则可以将一个方法与同一类中的其他方法隔离开来。这是单元测试的目标。

见这个例子:

<?php

class User {

    public function years()
    {
        return floor($this->months() / 12);
    }

    public function months()
    {
        // Database call or anything else, it's a black box !
    }

}

class UserTest extends TestCase {

    public function testYearsReturnTheNumberOfYears() 
    {
        $user = \Mockery::mock('User[months]');
        $user->shouldReceive('months')->andReturn(18);

        assertEquals(1, $user->years());
    }

}

即使方法months被破坏,测试也会通过。请阅读mockery documentation以获取更多说明。

模拟是单元测试的关键。如果没有此工具,当您的代码中出现问题时,所有测试都会失败,您无法找到错误的来源。 PHP不够灵活,无法模拟Ruby或Javascript中的所有内容,但是如果设计模式良好,您可以做得很好。

一个非常好的例子是Laravel,其中所有的核心类都可以被嘲笑。像这样,您可以模拟数据库调用或电子邮件发送中的错误。

答案 1 :(得分:2)

我遇到了类似的问题。我必须使用依赖注入来模拟相同的类方法。所以部分嘲笑Mockery ......

$mock = Mockery::mock('MyClass[methodToMock1, methodToMock2]', array('constructor parameter 1', 'constructor parameter 2'));
$mock->shouldReceive('methodToMock1')->once()->andReturn('someValue');
$mock->shouldReceive('methodToMock2')->once()->andReturn('someValue2');
$this->assertTrue($mock->methodNum3(), 'some assert');

希望这会对某人有所帮助。