如何在模型测试用例中创建模拟

时间:2012-06-22 07:45:56

标签: unit-testing cakephp mocking phpunit cakephp-2.1

也许我做错了。

我想测试模型的beforeSave方法(抗体)。此方法的一部分调用关联模型(Species)上的方法。我想嘲笑物种模型,但不知道如何。

是否有可能或者我做的事情违背了MVC模式,从而尝试做一些我不应该做的事情?

class Antibody extends AppModel {
    public function beforeSave() {

        // some processing ...

        // retreive species_id based on the input 
        $this->data['Antibody']['species_id'] 
            = isset($this->data['Species']['name']) 
            ? $this->Species->getIdByName($this->data['Species']['name']) 
            : null;

        return true;
    }
}

2 个答案:

答案 0 :(得分:6)

假设您的Species模型由于关系而由蛋糕创建,您可以简单地执行以下操作:

public function setUp()
{
    parent::setUp();

    $this->Antibody = ClassRegistry::init('Antibody');
    $this->Antibody->Species = $this->getMock('Species');

    // now you can set your expectations here
    $this->Antibody->Species->expects($this->any())
        ->method('getIdByName')
        ->will($this->returnValue(/*your value here*/));
}

public function testBeforeFilter()
{
    // or here
    $this->Antibody->Species->expects($this->once())
        ->method('getIdByName')
        ->will($this->returnValue(/*your value here*/));
}

答案 1 :(得分:0)

嗯,这取决于'Species'对象的注入方式。 它是通过构造函数注入的吗?通过二传手?它是继承的吗?

以下是构造函数注入对象的示例:

class Foo
{
    /** @var Bar */
    protected $bar;

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

    public function foo() {

        if ($this->bar->isOk()) {
            return true;
        } else {
            return false;
        }
    }
}

然后你的测试会是这样的:

public function test_foo()
{
    $barStub = $this->getMock('Overblog\CommonBundle\TestUtils\Bar');
    $barStub->expects($this->once())
        ->method('isOk')
        ->will($this->returnValue(false));

    $foo = new Foo($barStub);
    $this->assertFalse($foo->foo());
}

使用setter注入的对象的过程非常相似:

public function test_foo()
{
    $barStub = $this->getMock('Overblog\CommonBundle\TestUtils\Bar');
    $barStub->expects($this->once())
        ->method('isOk')
        ->will($this->returnValue(false));

    $foo = new Foo();
    $foo->setBar($barStub);
    $this->assertFalse($foo->foo());
}