不使用PHPUnit测试受保护/私有方法时的代码覆盖率 [英] Code coverage when not testing protected/private methods with PHPUnit

查看:87
本文介绍了不使用PHPUnit测试受保护/私有方法时的代码覆盖率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道可以使用反射或其他变通办法通过PHPUnit测试私有/受保护的方法.

I know it's possible to test private/protected methods with PHPUnit using reflection or other workarounds.

但是大多数消息来源告诉我,在类内部为私有方法编写测试不是不是最佳实践.

But most sources tell me that it's not best practice to write tests for private methods inside of a class.

您应该像模拟黑匣子"一样测试类-您可以通过比较输入和输出而不考虑内部机制来测试预期的行为.为类编写测试还应该通过显示代码覆盖不足来通知您未使用的私有方法.

You are supposed to test the class as if it were a "black box" — you just test for expected behavior by comparing inputs with outputs disregarding the internal mechanics. Writing tests for classes should also notify you to unused private methods, by showing lack of code coverage.

当我测试我的类并生成HTML报告时,即使绝对地执行/覆盖了调用它们的行,它也会显示测试未涵盖的私有方法.我知道私有方法会执行,因为如果不是,那么我的类上的断言就不会通过.

When I test my class and generate an HTML report, it shows the private methods as not covered by tests, even though the lines from which they are called are absolutely executed/covered. I know that the private methods are executed, because if they weren't the assertions on my class would not pass.

这是PHPUnit中的预期行为吗?我可以争取100%的覆盖率,同时仍然只能间接测试私有方法吗?

Is this expected behavior in PHPUnit? Can I strive for 100% coverage, while still testing private methods only indirectly?

一些简化的示例代码(在Symfony2中使用RestBundle):

Some simplified example code (using RestBundle in Symfony2):

class ApiController extends FOSRestController {

/*
 * @REST\View()
 * @REST\Get("/api/{codes}")
 */
public function getCodesAction($codes) {
    $view = new View();
    $view->setHeader('Access-Control-Allow-Origin', '*');
    $view->setData(array('type' => 'codes','data' => $this->_stringToArray($codes)));
    $view->setFormat('json')->setHeader('Content-Type', 'application/json');
    return $this->handleView($view);
}

private function _stringToArray($string){
    return explode('+',$string);
}

公共功能显示为已覆盖",私有功能被间接覆盖,但在PHPUnit报告中显示为红色.

The public function shows as "covered", the private function is indirectly covered but shows colored red in PHPUnit reports.

测试:

class ApiControllerTest extends WebTestCase {

    public function test_getCodesAction(){
        $client = static::createClient();
        $client->request('GET', '/api/1+2+3');
        $this->assertContains('{"type": "codes", "data": [1,2,3]}', $client->getResponse()->getContent());
    }

}

这当然是一个愚蠢的例子,我也可以将explode()包含在public函数中.但是我正在编写测试的控制器包含更多复杂且可重复使用的私有函数,这些私有函数以更复杂的方式转换数据(但仍然没有副作用).

This is just a silly example of course, I could just as well include the explode() right there in the public function; But the controllers I'm writing tests for contain much more intricate and re-usable private functions which transform data in more complex ways (but are still side-effect free).

推荐答案

在Phpunit中,您可以指定带有特殊注释的Covered Methods,如

In Phpunit you can specify the Covered Methods with special annotation, as descrived in the doc.

您可以执行以下操作:

    class ApiControllerTest extends WebTestCase {

        /**
         * @covers ApiController::getCodesAction
         * @covers ApiController::_stringToArray
         */
        public function test_getCodesAction(){
            $client = static::createClient();
            $client->request('GET', '/api/1+2+3');
            $this->assertContains('{"type": "codes", "data": [1,2,3]}', $client->getResponse()->getContent());
        }

    }

希望获得帮助

这篇关于不使用PHPUnit测试受保护/私有方法时的代码覆盖率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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