对不适合提取为新 class 的私有方法进行单元测试的好方法是什么?
What is a good way to unit test private methods that are not suitable to be extracted as a new class?
粗略地说,我有一个 class 实现了一个只有一个 public 方法的线程 run
。该方法进入循环,就像调度程序一样,一条一条地处理网络消息;像下面这样:
class WorkerThread {
public:
void run() {
while (!b_shutdown) {
message = getNextMessage();
switch(message.type) {
case WRITE:
write();
case READ:
read();
// ...
// more cases to handle
}
}
}
private:
void write() { /* logic to test */ }
void read() { /* logic to test */ }
// more private methods with logic that needs testing
// some member variables
};
所以重点是我真的不想
- 将私有方法提取到另一个 class,因为从语义上讲它们是此
WorkerThread
. 的一部分
- 制作方法 public,因为它们不会在 class.
之外的任何地方使用
- 跳过测试,因为正是这些方法实现了主要逻辑。
但是私有方法如何优雅地进行测试呢?
注:
- 可能还需要一些 public 方法来处理线程的启动和终止,但这不是这里要考虑的问题。
- 我认为这个问题不局限于
c++
,所以我也用更流行的静态类型Java
标记它,以引起更多关注:P
简单地说:不要。针对 public 接口进行测试,仅此而已。最终,这是唯一重要的事情。
如果您想查看它是否正常工作,应该通过 IoInterface
访问 read/write 函数,可以模拟它进行测试。
引用问题:
I really don't want to extract the private methods out to another class, because semantically they are part of this WorkerThread.
那是错误的。您违反了 Single Responsibility Principle。
提供 "multi threading support" 和 "doing actual work" 是 两个 不同的东西。您应该 而不是 强制 "doing the actual work" 是私有实现细节。
从这个意义上说:您为自己制定的规则实际上导致您编写难以测试 代码。因此,与其 "working around" 糟糕设计的症状 - 不如退后一步,修复 您的设计。
换句话说:
- 重做你的工作线程以能够运行任何类型的工作
- 单独关注;并将 "this kind of work" 放入专门的 class
这样做,不仅会改进您的设计,还会使测试更容易:因为现在,您可以进行单元测试 "doing the actual work" 而无需 多线程的复杂性。您只需断言这些东西在按顺序完成时有效。然后你自己测试多线程部分;无需担心实际工作。最后,一切都很好地结合在一起。
而不是你担心如何测试内部实现细节。哪个-你没有;另一个答案完全正确!
粗略地说,我有一个 class 实现了一个只有一个 public 方法的线程 run
。该方法进入循环,就像调度程序一样,一条一条地处理网络消息;像下面这样:
class WorkerThread {
public:
void run() {
while (!b_shutdown) {
message = getNextMessage();
switch(message.type) {
case WRITE:
write();
case READ:
read();
// ...
// more cases to handle
}
}
}
private:
void write() { /* logic to test */ }
void read() { /* logic to test */ }
// more private methods with logic that needs testing
// some member variables
};
所以重点是我真的不想
- 将私有方法提取到另一个 class,因为从语义上讲它们是此
WorkerThread
. 的一部分
- 制作方法 public,因为它们不会在 class. 之外的任何地方使用
- 跳过测试,因为正是这些方法实现了主要逻辑。
但是私有方法如何优雅地进行测试呢?
注:
- 可能还需要一些 public 方法来处理线程的启动和终止,但这不是这里要考虑的问题。
- 我认为这个问题不局限于
c++
,所以我也用更流行的静态类型Java
标记它,以引起更多关注:P
简单地说:不要。针对 public 接口进行测试,仅此而已。最终,这是唯一重要的事情。
如果您想查看它是否正常工作,应该通过 IoInterface
访问 read/write 函数,可以模拟它进行测试。
引用问题:
I really don't want to extract the private methods out to another class, because semantically they are part of this WorkerThread.
那是错误的。您违反了 Single Responsibility Principle。
提供 "multi threading support" 和 "doing actual work" 是 两个 不同的东西。您应该 而不是 强制 "doing the actual work" 是私有实现细节。
从这个意义上说:您为自己制定的规则实际上导致您编写难以测试 代码。因此,与其 "working around" 糟糕设计的症状 - 不如退后一步,修复 您的设计。
换句话说:
- 重做你的工作线程以能够运行任何类型的工作
- 单独关注;并将 "this kind of work" 放入专门的 class
这样做,不仅会改进您的设计,还会使测试更容易:因为现在,您可以进行单元测试 "doing the actual work" 而无需 多线程的复杂性。您只需断言这些东西在按顺序完成时有效。然后你自己测试多线程部分;无需担心实际工作。最后,一切都很好地结合在一起。
而不是你担心如何测试内部实现细节。哪个-你没有;另一个答案完全正确!