简体   繁体   English

PHPUnit和Abstract类:如何测试接受参数和其他具体方法的具体构造函数

[英]PHPUnit and Abstract classes: how to test concrete constructor that accepts parameters and other concrete methods

I have a very simple class like this one below: 我有一个非常简单的类,如下所示:

abstract class Person
{
    private $id;
    private $createdOn;

    // ... More private properties

    protected $unfound = array();

The constructor does a foreach on the passed array $data and, using the correct methods, assigns values to properties. 构造函数对传递的数组$ data执行操作,并使用正确的方法将值分配给属性。 If the method doesn't exist, then the key is added to a protected array to keep a trace of it (i called it $unfound, just to be original!). 如果该方法不存在,那么将密钥添加到受保护的数组中以保留它的跟踪(我称之为$ unfound,只是为了原始!)。

    public function __construct($data)
    {
        foreach ($data as $field => $value)
        {
            $method = 'set' . ucfirst($field);

            if (method_exists($this, $method))
            {
                $this->$method($value);
            }
            else
            {
                $this->unfound[] = $field;
            }
        }
    }

The list of methods to set the values for properties 设置属性值的方法列表

    public function setId($id) {
        $this->id = $id;
    }

    public function setCreatedOn($createdOn) {
        $this->createdOn = $createdOn;
    }

And a list of methods to get those assigned values 以及获取这些指定值的方法列表

    public function getId() {
        return $this->id;
    }

    public function getCreatedOn() {
        return $this->createdOn;
    }
} // END of the class

As you can see, the class doesn't do any complicated task: it accepts an array like 如您所见,该类不执行任何复杂的任务:它接受类似的数组

array(
    'id' => 4,
    'createdOn' => '2015-01-07 20:50:00',
    'unknownVar' => 'mah'
    // ... Other properties to set
    );

So the class cycles through the array and use the key to call the correct method to set the value. 因此,类循环遍历数组并使用键调用正确的方法来设置值。 Nothing complex i think. 我觉得没什么复杂的。

More complex is, instead, testing it. 相反,更复杂的是测试它。

As it is an abstract class, i cannot instantiate it directly, but i have to mock it. 因为它是一个抽象类,我不能直接实例化它,但我必须嘲笑它​​。

My problem is that i can't pass to constructor the correct parameters to test if the values assignment is correctly done. 我的问题是,我无法传递给构造函数正确的参数来测试值分配是否正确完成。

I've tried to use something like: 我试过用类似的东西:

public function testPerson()
{
   $abstractClass = '\My\Namespace\Person';

    $testData = array(
        'id' => 1,
        'createdOn' => '2015-01-07 19:52:00',
        'unfound' => 'Inexistent method'
        );

   $methods = array(
      'getId',
      'setId'
      );

    $mock = $this->getMockBuilder($abstractClass)
        ->setConstructorArgs(array($testData))
        ->setMethods($methods)
        ->getMockForAbstractClass();

    $this->assertEquals($testData['id'], $mock->getId());
}

In testPerson(), the $methods variable doesn't contain all methods i need, but for the testing of the test (please, excuse me for the play with words! :) ) i think they are sufficient. 在testPerson()中,$ methods变量不包含我需要的所有方法,但是对于测试的测试(请原谅我玩文字!:))我认为它们已经足够了。

But PHPUnit tells me that: 但PHPUnit告诉我:

Failed asserting that null matches expected 1.

It seems like the constructor isn't called, also if the code coverage tells me that methods are called. 似乎构造函数没有被调用,如果代码覆盖率告诉我方法被调用。

is there anyone who can help me understand what is happening and how can i test this class? 是否有人可以帮助我了解正在发生的事情以及如何测试这门课程?

Thank you! 谢谢!

The solution is very simple: deleting the $methods variable and the calling to setMethods($methods) solved the problem! 解决方案非常简单:删除$methods变量并调用setMethods($methods)解决了这个问题!

Calling setMethods() , in fact, "stubs" those methods that, without setting a proper fixed value, are set to null ( the value I received from the tests result ). 事实上,调用setMethods() ,“stubs”那些没有设置适当的固定值的方法被设置为null( 我从测试结果中收到的值 )。

The method I tested was stubbed whereas the others not. 我测试的方法是顽固的而其他方法没有。

So a print_r($mock) revealed that other values were correctly set. 所以print_r($mock)显示其他值已正确设置。

So simple but so hard to find! 这么简单但很难找到! Thank you anyway to you to make me think, so I solved the problem and asked the question! 无论如何,谢谢你让我思考,所以我解决了问题并提出了问题!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM