如何编写 JUnit 测试用例来测试线程和事件
我有一个在一个(主)线程中工作的java代码。从主线程中,我生成一个新线程,在其中进行服务器调用。服务器调用完成后,我在新线程中执行一些工作,然后代码加入主线程。
我正在使用 eclipse Jobs 进行服务器调用。
我想知道如何为此编写 JUnit 测试用例。
I have a java code which works in one (main) thread. From the main thread, i spawn a new thread in which I make a server call. After the server call is done, I am doing some work in the new thread and after that the code joins the main thread.
I am using eclipse Jobs to do the server call.
I want to know, how do I write a JUnit test case for this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可能需要重组代码以便可以轻松测试。
我可以看到几个不同的测试区域:
构建您的实现这样您的线程管理代码就无法了解 Worker 的详细信息。然后,您可以使用 Mock Workers 来启用线程管理测试 - 例如,以某些方式失败的 Mock Worker 允许您测试管理代码中的某些路径。
实现 Worker 代码,使其可以独立运行。然后,您可以使用服务器的模拟来独立进行单元测试。
对于并发测试,Abhijeet Kashnia 提供的链接将有所帮助。
You may need to restructure your code so that it can be easily tested.
I can see several distinct areas for testing:
Structure your implementation so that Your Thread Management code is agnostic as to the details of the Worker. Then you can use Mock Workers to enable testing of Thread Management - for example a Mock Worker that fails in certain ways allows you to test certain paths in the management code.
Implement the Worker code so that it can be run in isolation. You can then unit test this independently, using mocks for the server.
For concurrency testing the links provided by Abhijeet Kashnia will help.
这就是我创建 ConcurrentUnit 的目的。一般用法是:
有关详细信息,请参阅 ConcurrentUnit 页面。
This is what I created ConcurrentUnit for. The general usage is:
See the ConcurrentUnit page for more info.
Abhijeet Kashnia 提供的资源可能会有所帮助,但我不确定您想要实现什么目标。
您可以使用模拟进行单元测试来验证您的代码,这不会测试并发性,但会提供覆盖率。
您可以编写集成测试来验证线程是否按照您期望的方式创建和连接。但是,这不能保证不会出现并发问题。大多数并发问题是由不可预测的计时错误引起的,因此无法准确测试。
The resources provided by Abhijeet Kashnia may help, but I am not sure what you are trying to achieve.
You can do unit testing with mocks to verify your code, that won't test concurrency but will provide coverage.
You can write an integration test to verify that the threads are being created and joined in the fashion you expect.However this will not guarantee against concurrency problems. Most concurrent problems are caused by timing bugs which are not predictable and thus can't be tested for accurately.
当您唯一的问题是等待结果时,请使用 ExecutorService 用于生成线程。它可以接受工作作业作为 Runnable和可调用。当您使用后者时,您将获得 Future 返回对象,可用于等待结果。无论如何,您应该考虑使用ExecutorService,据我了解,您创建了许多线程,这是执行程序服务的完美用例。
和测试类:
When your only problem is waiting for the result, use ExecutorService for spawning your threads. It can accept work jobs both as Runnable and Callable. When you use the latter, then you are given a Future object in return, that can be used to wait for the result. You should consider using ExecutorService anyway, as from what I understand, you create many threads, and this is a perfect use case for executor services.
And the test class:
我建议您使用模拟框架来确认确实进行了服务器调用。至于线程单元测试:对多线程应用程序进行单元测试
I suggest you use a mocking framework, to confirm that the server call was indeed made. As for the thread unit testing: Unit testing multithreaded applications
我猜您可能已经完成了模拟代码,并且可能需要一个简单的集成测试来确保您的服务器调用正常工作。
测试线程的困难之一来自于它们的本质——它们是并发的。这意味着您被迫编写 JUnit 测试代码,该代码被迫等待线程完成其工作后再测试代码的结果。这不是测试代码的好方法,并且可能不可靠,但通常意味着您对代码是否正常工作有一定的了解。
例如,您的代码可能看起来像这样:
我真的不喜欢这样做,更喜欢模拟并同意其他答案。但是,如果您需要测试线程,那么这是我认为有效的一种方法。
I'm guessing that you may have done your mocking code and may want a simple integration test to ensure that that your server call works.
One of the difficulties in testing threads comes from their very nature - they're concurrent. This means that you're force into writing JUnit test code that is forced to wait until your thread has finished its job before testing your code's results. This isn't a very good way of testing code, and can be unreliable, but usually means that you have some idea about whether you code is working.
As an example, your code may look something like:
I really don't like doing this and prefer mocks and agree with the other answers. But, if you need to test your threads, then this is one approach that I find works.
这是我使用 thread.start 测试异步方法的解决方案:
Here is my solution to test asynchrone method which used thread.start: