当您使用私有方法的知识来选择测试用例时,您是否明确对私有方法进行单元测试 [英] Are you explicitly unit testing a private method when you use your knowledge of the private method to choose test cases

查看:23
本文介绍了当您使用私有方法的知识来选择测试用例时,您是否明确对私有方法进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎测试社区的普遍共识是测试私有方法.相反,您应该通过测试调用它们的公共方法来测试私有方法.然而,我觉得有些不对劲.我们以这个方法为例:

/*** 返回输出生成器类的基本名称.如果类被命名* Reno_OutputGenerator_HTML,这将返回HTML".** @return 字符串*/受保护的函数 getName(){$class = get_class($this);$matches = array();if (preg_match('/^Reno_OutputGenerator_(.+)$', $class, $matches)){返回 $matches[1];}别的{throw new Reno_OutputGenerator_Exception('类名必须遵循Reno_OutputGenerator_的格式.');}}

这个特殊的函数在我班上的几个地方使用.我想在这个函数中测试 if 语句的两个分支,这意味着对于每个公共函数,我必须测试这两种情况以及公共方法本身所做的任何其他事情.>

这让我觉得很奇怪.如果我正在测试以查看 getName() 在满足某个特定条件时是否抛出异常,那么这意味着我必须知道私有方法的实现细节.如果我必须知道这一点,那我为什么不直接扩展类,将方法公开,然后以这种方式进行测试?

(顺便说一句:如果你想知道为什么会有这样一个奇怪的方法,它用于自动找出这个类的模板文件存储在哪个目录中).

解决方案

我理解单元测试的方式,这正是我想要做的那种测试.我一直将单元测试视为白盒测试;如果我的代码中有一个分支点,这意味着我需要两个单元测试来解决它.我认为我遇到的最糟糕的情况是具有 32 个排列的单一方法.

单元测试的挑战在于,如果您不通过检查代码并找出所有不同路径来探索所有边缘情况,您最终会遗漏一个或多个案例,并可能在您的应用程序中引入细微的错误.

所以,不,我不认为你提出的建议很奇怪.该方法可以保留在内部,并且您可以添加一个额外的测试用例 - 您可能只需要一个有异常的,对吧?

或者,您可以将功能重构为一个单独的对象,该对象接受您的生成器对象并返回其名称(基于上述算法).这将证明将测试分开是合理的,因为您有一个名称提取器对象和输出生成器实现.我仍然不确定这是否会为您节省很多,因为您仍然需要测试输出生成器以确保它们正确使用名称提取器,但它会将您的功能和测试问题分开.

It seems as though the general consensus of the testing community is to not test private methods. Instead, you should test private methods by testing the public methods that invoke them. However, something just doesn't feel right to me. Let's take this method for example:

/**
 * Returns the base name of the output generator class. If the class is named
 * Reno_OutputGenerator_HTML, this would return "HTML".
 *
 * @return string
 */
protected function getName()
{
    $class = get_class($this);
    $matches = array();

    if (preg_match('/^Reno_OutputGenerator_(.+)$', $class, $matches))
    {
        return $matches[1];
    }
    else
    {
        throw new Reno_OutputGenerator_Exception('Class name must follow the format of Reno_OutputGenerator_<name>.');
    }
}

This particular function is used in a couple of places in my class. I'd like to test both branches of the if statement in this function, which would mean for each public function I'd have to test those 2 situations plus whatever else the public method itself does.

This is what feels weird for me. If I'm testing to see if getName() throws an Exception when a certain specific condition is met, then that means that I have to know implementation details of the private method. If I have to know that, then why shouldn't I just extend the class, make the method public, and test it that way?

(BTW: If you're wondering why such a weird method exists, this is used to automagically figure out what directory this class's template files are stored in).

解决方案

The way I understand unit testing, this is exactly the kind of testing I would want to do. I have always looked at unit testing as white-box testing; if there's a branch point in my code, that means I need two unit tests to address it. I think the worst case I ever wound up with was a single method with 32 permutations.

The challenge with unit-testing is that if you don't explore all the edge cases by examining your code and figuring out all the different paths, you wind up missing one or more cases and possibly introducing subtle bugs into your application.

So, no, I don't see what you're proposing as weird. The method can stay internal, and you can add an extra test case - you probably only need the one with the exception, right?

Alternatively, you could refactor the functionality into a separate object that takes your generator object and returns its name (based on the algorithm above). That would justify separating the tests, because you'd have a name-extractor object, and the output generator implementations. I'm still not sure that this would save you a lot, because you'd still have to test the output generators to make sure they were using the name extractor correctly, but it would separate your functional and testing concerns.

这篇关于当您使用私有方法的知识来选择测试用例时,您是否明确对私有方法进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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