好吧,我是单位测试新手(使用phpUnit),刚刚开始测试我的一类。
实际构造函数如下所示:
/**
* Loads configuration.
*/
function __construct() {
$config =
Kohana::$config->load('koffee');
$this->_table_name = $config->table_name;
$this->_table_columns = $config->table_columns;
}
它基本上从另一个文件获取配置,并将其设置为该对象的受保护属性。
以下是单元测试的外观(它还没有完成,这就是我需要帮助的地方):
/**
* Tests that config is loaded and correct.
*/
function testConfigIsLoadedAndCorrect() {
$object = new Model_Article();
$config = Kohana::$config->load('koffee');
// Compare object's **protected** properties to local `$config`. How?!
}
问题是属性受到保护,我无法轻易访问它们......
我目前看到的可能的解决方案:
这对你来说可能很有意思,但正如我所说,我是单位测试的新手。任何帮助非常感谢。
答案 0 :(得分:8)
单元测试是关于 单元 测试。受保护的成员不是单元的公共接口的一部分,这是编写单元测试时应该关注的所有内容。
您不测试单位的内部胆量,但它可以按预期工作。
如果您不想这样做,可以使用SerializationDocs,casting to array和ReflectionDocs来检查对象的受保护/私有属性或执行protected / private方法一个对象。
答案 1 :(得分:2)
我过去使用的一种技术是创建一个Tester类,它公开了测试对象的适当方法。在这种情况下,Model_Article_Tester
会继承Model_Article
并公开get
方法。这样做的好处是可以在不影响生产代码的情况下公开测试所需的内容。
答案 2 :(得分:2)
您可以创建一个公开所需数据的子类,并仅将其用于单元测试。
您还可以测试类的行为而不是数据。 Model_Article必须对table_name和table_columns执行某些操作,以便测试该行为。例如,如果Model_Article用于创建html表,那么您可以设置配置值,创建Model_Article,使用它来创建html,然后声明它匹配像<table title='name'><tr><th>col1</th><th>col2</th</tr></table>
这样的硬编码字符串
[edit]你也可以依靠构造函数注入来传递table_name和table_columns,而不是对配置有隐藏的依赖。
答案 3 :(得分:0)
您可以尝试使用ReflectionClass::newInstanceWithoutConstructor
$reflector = new ReflectionClass('Model_Article');
$object = $reflector->newInstanceWithoutConstructor();