我有一个UDPlistener应用程序,我需要编写单元测试。此侦听器持续侦听端口,并且始终在产品上运行。我们将poco库用于不在标准库中的框架。
现在我需要将它添加到单元测试应用程序中。
我认为在运行应用程序的类Poco::Runnable
中实现RunApp
是最简单的。然后我可以在单元测试中创建一个新的Poco::Thread
来运行RunApp
类。
这有效;我的监听器正在运行,我可以在生成线程后在单元测试体中发送测试消息。但是,我需要停止监听器,以便其他单元测试可以运行。我添加了一条UDP消息,告诉监听器自杀,但这仅用于单元测试和潜在的安全问题。
有没有办法迫使Poco::Thread
停止?或者我构建这个单元测试错了?我不希望监听器在所有其他单元测试期间运行。
答案 0 :(得分:7)
如果不使用Poco::Thread
而使用Poco::Task
,则可以获得可以取消的线程。以下示例代码(准备按原样运行)应该会给您一个想法:
#include <Poco/Task.h>
#include <Poco/TaskManager.h>
#include <Poco/Thread.h>
#include <string>
#include <iostream>
using namespace std;
class UdpListenerTask : public Poco::Task {
public:
UdpListenerTask(const string& name) : Task(name) { }
void runTask() {
cout << name() << ": starting" << endl;
while (! isCancelled()) {
// Do some work. Cannot block indefinitely, otherwise it
// will never test the isCancelled() condition.
doSomeWork();
}
cout << endl << name() << ": cancelled " << endl;
}
private:
int doSomeWork() {
cout << "*" << flush;
// Simulate some time spent doing work
int i;
for (i = 0; i < INT32_MAX/1000; i++) { }
return i;
}
};
void runUdpProbe() {
// Simulate some time spent running the probe.
Poco::Thread::sleep(1000);
}
int main() {
Poco::TaskManager tm;
UdpListenerTask* st = new UdpListenerTask("task1");
tm.start(st); // tm takes ownership
// Run test 1.
runUdpProbe();
// Test 1 done. Cancel the UDP listener
st->cancel();
// Run all the other tests
// cleanup
tm.joinAll();
return 0;
}
POCO幻灯片Multithreading给出了Poco :: Thread和Poco :: Task的使用示例。
另外,单元测试应该通过抽象类和模拟对象绕过UDP通信;我认为这个测试应该被称为特征测试: - )