OO 中的单元测试和访问修饰符
Unit Testing and Access modifiers in OO
我注意到,为了对OO代码中的每个单元进行单元测试,我需要将访问修饰符设置为公共,即使在应该受保护或可能是私有的方法上也是如此。这是可以练习的吗?
public class EnforceBusinessRules
{
BusinessState m_state;
public EnforceBusinessRules()
{
m_state = START;
}
public bool isInputcurrentlyFormatted(string input)
{
//code goes here to ensure the input passes formatting test
//modify m_state appropriately
}
public bool InputContainsValidStartAndEndTokens(string input)
{
//code goes here to ensure that the start and end tokens of the input are of the type available in the system
//modify m_state appropriately
}
public bool StartEndCommandisValidAccordingtoCurrentSystemSettings(string input)
{
//code goes here to check the start and End codes match the current start and end codes for the day
//modify m_state appropriately
}
// and so on
}
单元测试是"黑盒"测试。您应该只测试外部可见元素。如果你测试了所有的内部工作,那么如果不修改所有的单元测试,你就无法正确地重构你的代码。
如果您发现需要更改访问修饰符,因为私有成员中有大量代码需要测试,这可能表明您的类太大。 考虑将要测试的行为分解为具有可测试的公共接口的较小类。 您的代码可能正在遭受上帝对象代码气味的困扰。
请记住,受保护的成员与公共成员非常相似,只是可能的客户端的空间要小得多(仅限派生类)。 您可以考虑通过创建仅测试使用的派生对象来对这些方法进行单元测试。 这样,您将以与客户使用它们相同的方式测试这些方法。
以下是修改代码的一种方法:
public class EnforceBusinessRules
{
BusinessState m_state;
public EnforceBusinessRules(IEnumerable<Rule> rules)
{
m_state = START;
}
public void Enforce(string input)
{
foreach (var rule in rules)
{
m_state = rule.EnforceRule(input);
}
}
}
public interface Rule
{
public BusinessState EnforceRule(string input);
}
public class IsInputcurrentlyFormatted : Rule
{
public BusinessState EnforceRule(string input)
{
//code goes here to ensure the input passes formatting test
}
}
public class InputContainsValidStartAndEndTokens : Rule
{
public BusinessState EnforceRule(string input)
{
//code goes here to ensure the input passes formatting test
}
}
public class StartEndCommandisValidAccordingtoCurrentSystemSettings : Rule
{
public BusinessState EnforceRule(string input)
{
//code goes here to ensure the input passes formatting test
}
}
// and so on
No.在我看来,你想错了。你可以在不公开的情况下推断事物。例如,属性的值可以从函数返回中实现。
在受保护成员的情况下。问问自己这意味着什么。这意味着派生类可以访问该成员。因此,在测试中创建一个派生类型。
听起来您未能创建 getter 和 setter 方法,以便正确封装您的私有数据。
单元测试应通过 getter 和 setter 访问数据。
避免在类代码中实例化协作对象,而是注入这些依赖项。
通常,将方法/类/属性/任何内容公开给您不想公开的外部世界都是不好的做法。 我们在我工作的地方遇到了类似的问题。 我们编写了命中公共方法和属性的测试,因为这些公共方法应该在某个时候调用所有私有方法。 如果您有内部类/属性/方法,则可以使用 InternalsVisableTo
属性来访问单元测试库。
[assembly: InternalsVisibleTo("AssemblyB")]
http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx
如果需要测试私有或受保护的属性或方法,则应将功能提取到单独的类中。每个类应该只做一件事(单一责任原则)。您的私有方法很可能在类的主要目的上执行辅助功能。
提取后,会发生两件好事:首先,您希望测试的代码现在可以通过单元测试完全访问。其次,您不必担心在EnforceBusinessRules课程中
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- VC++本机单元测试,找不到调试符号
- 用于交叉编译和CMake的预处理器宏的单元测试
- C++ 用于单元测试的模板模板
- 提升 1.64 单元测试编译失败
- 单元测试欧拉到四元数实现失败
- 运行 C++ 单元测试时LNK2005链接错误
- 禁用自动捕获 Googletest 单元测试中的C++异常
- 有没有办法在不使用 #ifdef 的情况下不编译发布版本中的单元测试函数体?
- 使用 Google Test 对自定义断言函数进行单元测试
- 如何将我的 CMake 项目配置为运行所有单元测试?
- 在Qt C++单元测试中动态加载QQuickWindow而不是QQuickWidget
- MS 本机单元测试 - 断言::线程失败不起作用
- 如何获取 CMake 单元测试的相对路径?
- 在单元测试项目中包括 .c 文件,并从多个 cpp 文件访问它而不会出现链接问题
- Boost单元测试夹具继承测试类,是否可以访问受保护的方法
- 如何在单元测试中访问私有成员
- OO 中的单元测试和访问修饰符
- 访问私有变量的单元测试