在PHPUnit中测试具有依赖项的对象 [英] Testing objects with dependencies in PHPUnit

查看:103
本文介绍了在PHPUnit中测试具有依赖项的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于组成另一个对象作为其实现的一部分的对象,编写单元测试的最佳方法是什么,以便仅对主对象进行测试?简单的例子:

For objects which compose another object as part of their implementation, what's the best way to write the unit test so only the principle object gets tested? Trivial example:

class myObj { 
    public function doSomethingWhichIsLogged()
    {
        // ...
        $logger = new logger('/tmp/log.txt');
        $logger->info('some message');
        // ...
    }
}

我知道可以对对象进行设计,以便可以在单元测试中注入记录器对象依赖性并因此在模型中进行模拟,但这并非总是如此-在更复杂的场景中,您确实需要组合其他对象或进行调用静态方法.

I know that the object could be designed so that the logger object dependency could be injected and hence mocked in a unit test, but that's not always the case - in more complicated scenarios, you do need to compose other objects or make calls to static methods.

由于我们不想测试记录器对象,而仅是myObj,我们该如何进行?我们是否使用测试脚本创建存根的"double"?像这样:

As we don't want to test the logger object, only the myObj, how do we proceed? Do we create a stubbed "double" with the test script? Something like:

class logger
{
    public function __construct($filepath) {}
    public function info($message) {}
}

class TestMyObj extends PHPUnit_Framework_TestCase 
{
    // ...
}

这对于小型对象似乎是可行的,但对于SUT依赖于返回值的更复杂的API而言,这将是一个痛苦.此外,如果要像使用模拟对象一样测试对依赖对象的调用,该怎么办?有没有一种方法可以模拟由SUT实例化而不是传入的对象?

This seems feasible for small objects but would be a pain for more complicated APIs where the SUT depended on the return values. Also, what if you want to test the calls to the dependency object in the same was you can with mock objects? Is there a way of mocking objects which are instantiated by the SUT rather than being passed in?

我已经阅读了有关模拟的手册页,但是它似乎没有涵盖依赖关系是组合而不是聚合的情况.你如何做到的?

I've read the man page on mocks but it doesn't seem to cover this situation where the dependency is composed rather than aggregated. How do you do it?

推荐答案

您似乎已经知道,具体的类依赖关系使测试变得很困难(或完全不可能).您需要解耦该依赖关系.一个简单的更改不会破坏现有的API,而是默认使用当前行为,但是提供了一个覆盖它的钩子.有多种方法可以实现.

As you seem to be aware already, Concrete Class Dependencies makes testing hard (or outright impossible). You need to decouple that dependency. A simple change, that doesn't break the existing API, is to default to the current behaviour, but provide a hook to override it. There are a number of ways that this could be implemented.

某些语言的工具可以将模拟类插入代码中,但是我不知道对于PHP这样的东西.在大多数情况下,最好还是重构代码.

Some languages have tools that can inject mock classes into code, but I don't know of anything like this for PHP. In most cases, you would probably be better off refactoring your code anyway.

这篇关于在PHPUnit中测试具有依赖项的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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