Testing method that creates a new thread and the result obtained from the event (NUnit 2.6)

I have a class that has one public Start method, one private method and one Finishing event. Start call new Thread( private_method ) . The return value of the private method using the event. When this method completes, call this event.

Now I want to write a test for this class. If I write it like this:

  [Test] public void Test1() { SomeClass someObject = new SomeClass(); someObject.Finishing += new SomeClass.FinishingEventHandler((sender, a) => { Assert.True(false); }); someObject.Start(); // when this method will finish, then call event Finishing } 

This should be unsuccessful, but it is not. I think the Test1 method Test1 complete before the event is raised. So how can I check this code? As a testing method that creates a new thread, and the result is obtained from the event

+4
source share
4 answers

NUnit has a built-in function to wait for approval. It is called After:

 [Test] public void ShouldRaiseFinishedEvent() { SomeClass someObject = new SomeClass(); bool eventRaised = false; someObject.SomethingFinished += (o, e) => { eventRaised = true; }; someObject.DoSomething(); Assert.That(eventRaised, Is.True.After(500)); } 
+16
source
 [Test] public void ShouldRaiseFinishedEvent() { SomeClass someObject = new SomeClass(); AutoResetEvent eventRaised = new AutoResetEvent(false); someObject.SomethingFinished += (o, e) => { eventRaised.Set(); }; someObject.DoSomething(); Assert.IsTrue(eventRaised.WaitOne(TimeSpan.FromMilliseconds(500))); } 

This should work

+2
source

You're right.

First of all, NUnit and its various hosted environments have had or still have various defects and limitations around threads running as part of the test. In particular, if you are not sure that the thread is completed before the test is completed, then NUnit does not know that someone is executing the code that he will unload after the test returns. I remember this pattern regularly causing VS crashes when NUnit was executed from it using the Resharper integration, as well as random crashes and memory leaks of GUI and console players with NUnit.

However, you need to provide two things.

  • Elementary security of the test environment by combining all the threads that you create.
  • Throwing all exceptions that indicate the loss of test only to the main thread. This means that the background thread must report its results to the main thread and that it has Assert all the different invariants.

Even better structure your code so you can unit test without background threads - if possible.

+1
source

As already mentioned, you can use unit test multi-threaded components, but are not as clean as regular unit tests. I mostly met him in Acceptance Tests and had great success with .net 4 Task and Parallel . However, in this case, a simple dream may make you, but if you start to do many of these tests, you may need a more efficient way to do this.

 [Test] public void Test1() { bool wasCalled = false; SomeClass someObject = new SomeClass(); someObject.Finishing += new SomeClass.FinishingEventHandler((sender, a) => { wasCalled = true; }); someObject.Start(); // when this method will finish, then call event Finishing Thread.Sleep(2000); Assert.True(wasCalled); } 

Whatever you do, you need some time to make the test finish, and not hang forever, this can be done in the test itself or in some test libraries there is a Timeout you can decorate the test.

0
source

Source: https://habr.com/ru/post/1402994/


All Articles