如何测试工厂班级? [英] How to test factory classes?

查看:87
本文介绍了如何测试工厂班级?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出此类:

class MyBuilder {
    public function build($param1, $param2) {

        // build dependencies ...

        return new MyClass($dep1, $dep2, $dep3);
    }
}

如何对此类进行单元测试?

How can I unit test this class?

进行单元测试意味着我想测试其行为,因此我想对其进行测试以构建具有正确依赖关系的对象。但是, new 指令是硬编码的,我无法模拟它。

Unit-testing it means I want to test its behavior, so I want to test it builds my object with the correct dependencies. However, the new instruction is hardcoded and I can't mock it.

目前,我已经添加了类的名称作为参数(所以我可以提供模拟类的类名称),但是很丑:

For now, I've added the name of the class as a parameter (so I can provide the class name of a mock class), but it's ugly:

class MyBuilder {
    public function build($classname, $param1, $param2) {

        // build dependencies ...

        return new $classname($dep1, $dep2, $dep3);
    }
}

是否有干净的解决方案或设计模式可以使我

Is there a clean solution or design pattern to make my factories testable?

推荐答案

工厂本质上是可测试的,您只是想对实现进行过于严格的控制。

Factories are inherently testable, you are just trying to get too tight of control over the implementation.

您将检查是否通过 $ this-> assertInstanceOf()获得了类的实例。然后,使用结果对象,请确保正确设置了属性。为此,您可以使用任何公共访问器方法,也可以使用PHPUnit中可用的 $ this-> assertAttribute * 方法。

You would check that you get an instance of your class via $this->assertInstanceOf(). Then with the resulting object, you would make sure that properties are set properly. For this you could use any public accessor methods or use $this->assertAttribute* methods that are available in PHPUnit.

http://phpunit.de/manual/current/zh-CN/writing-tests-for-phpunit.html#writing-tests-for-phpunit.assertions.assertEquals

许多常见的断言也可以检查受保护和私有属性的属性。

Many of the common assertions also have the ability to check attributes for protected and private properties.

我不会在参数列表中指定类名,因为您的用法是工厂将仅返回一种类型,并且仅更改了依赖项。使它返回模拟对象类型是不必要的,并使您的测试更加复杂。

I wouldn't specify the classname in your parameter list, as your usage is that the factory will only return one type and it is only the dependencies that are changed. Making it return a mock object type is unnecessary and makes your test more complicated.

测试最终看起来像这样:

The test would end up looking like this:

public function testBuild() {
    $factory = new MyBuilder();

    //I would likely put the following into a data provider
    $param1 = 'foo';
    $param2 = 'bar';

    $depen1 = 'boo';
    $depen2 = 'baz';
    $depen3 = 'boz';

    $object = $factory->build($param1, $param2);

    $this->assertInstanceOf('MyClass', $object);

    //Check the object definition
    //This would change depending on your actual implementation of your class
    $this->assertAttributeEquals($depen1, 'attr1', $object);
    $this->assertAttributeEquals($depen2, 'attr2', $object);
    $this->assertAttributeEquals($depen3, 'attr3', $object);
}

您现在要确保工厂返回正确的对象。首先,请确保其类型正确。然后,确保已正确初始化它。

You are now making sure that your factory returns a proper object. First by making sure that it is of the proper type. Then by making sure that it was initialized properly.

您需要使用 MyClass 进行测试通过,但这不是一件坏事。您的工厂打算创建 MyClass 对象,因此,如果该类未定义,则您的测试肯定会失败。

You are depending upon the existence of MyClass for the test to pass but that is not a bad thing. Your factory is intended to created MyClass objects so if that class is undefined then your test should definitely fail.

具有在开发过程中通过测试失败也不是一件坏事。

Having failing tests while your developing is also not a bad thing.

这篇关于如何测试工厂班级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆