惯用语和可测性 [英] The pImpl idiom and Testability

查看:66
本文介绍了惯用语和可测性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

c ++中的pImpl习惯用法旨在向该类的用户隐藏该类的实现详细信息(=私有成员).但是,它也隐藏了该类的某些依赖关系,这些依赖关系从测试的角度通常被认为是不好的.

The pImpl idiom in c++ aims to hide the implementation details (=private members) of a class from the users of that class. However it also hides some of the dependencies of that class which is usually regarded bad from a testing point of view.

例如,如果类A将其实现细节隐藏在只能从A.cpp访问的类AImpl中,并且AImpl依赖于许多其他类,则对单元A进行单元测试将变得非常困难,因为测试框架无法访问AImpl的方法,也没有办法将依赖项注入AImpl.

For example if class A hides its implementation details in Class AImpl which is only accessible from A.cpp and AImpl depends on a lot of other classes, it becomes very difficult to unit test class A since the testing framework has no access to the methods of AImpl and also no way to inject dependency into AImpl.

有人以前遇到过这个问题吗?并找到解决方案了吗?

Has anyone come across this problem before? and have you found a solution?

-编辑-

在一个相关主题上,似乎有人建议应该只测试接口公开的公共方法,而不是内部方法.虽然我可以从概念上理解该声明,但我经常发现我需要单独测试私有方法.例如,当公共方法调用包含一些非平凡逻辑的私有帮助器方法时.

On a related topic, it seems that people suggest one should only test public methods exposed by the interface and not the internals. While I can conceptually understand that statement, I often find that I need to test private methods in isolation. For example when a public method calls a private helper method that contains some non trivial logic.

推荐答案

pimpl的想法不是要在类中隐藏实现细节(私有成员已经这样做了),而是将实现细节移出了标头.问题在于,在C ++的包含模型中,更改私有方法/变量将强制重新编译包括该文件在内的任何文件.这很痛苦,这就是pimpl寻求消除的原因.这不利于防止依赖外部库.其他技术可以做到这一点.

The idea behind pimpl is to not so much to hide implementation details from classes, (private members already do that) but to move implementation details out of the header. The problem is that in C++'s model of includes, changing the private methods/variables will force any file including this file to be recompiled. That is a pain, and that's why pimpl seeks to eliminate. It doesn't help with preventing dependencies on external libraries. Other techniques do that.

您的单元测试不应依赖于类的实现.他们应该验证您的课堂是否确实发挥了应有的作用.唯一真正重要的是对象如何与外界交互.测试无法检测到的任何行为都必须是对象内部的,因此是不相关的.

Your unit tests shouldn't depend on the implementation of the class. They should verify that you class actually acts as it should. The only thing that really matter is how the object interacts with the outside world. Any behavior which your tests cannot detect must be internal to the object and thus irrelevant.

已经说过,如果在类的内部实现中发现太多复杂性,则可能需要将该逻辑分解为单独的对象或函数.本质上,如果您的内部行为过于复杂而无法间接测试,则将其作为另一个对象的外部行为进行测试.

Having said that, if you find too much complexity inside the internal implementation of a class, you may want to break out that logic into a separate object or function. Essentially, if your internal behavior is too complex to test indirectly, make it the external behavior of another object and test that.

例如,假设我有一个类,该类将字符串作为其构造函数的参数.该字符串实际上是一种小型语言,用于指定对象的某些行为.(该字符串可能来自配置文件等).从理论上讲,我应该能够通过构造不同的对象并检查行为来测试该字符串的解析.但是,如果迷你语言足够复杂,这将很困难.因此,我定义了另一个函数,该函数接受字符串并返回上下文的表示形式(如关联数组或类似内容).然后,我可以与主要对象分开测试该解析功能.

For example, suppose that I have a class which takes a string as a parameter to its constructor. The string is actual a little mini-language that specifies some of the behavior the object. (The string probably comes from a configuration file or something). In theory, I should be able to test the parsing of that string by constructing different objects and checking behavior. But if the mini-language is complex enough this will be hard. So, I define another function that takes the string and returns a representation of the context (like an associative array or something). Then I can test that parsing function separately from the main object.

这篇关于惯用语和可测性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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