Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NUnit asserts in separate thread

Is nunit applicable in multithreading context. I do not want nunit to test my multithreading application of course, but want to use nunit assertions

Simple example - this test is "green". What do I wrong?

[Test]
public void Test()
{
  Action action = Async;
  action.BeginInvoke(action.EndInvoke, null).AsyncWaitHandle.WaitOne();
}

private void Async()
{
  Assert.IsTrue(false);
  Assert.DoesNotThrow( () =>
                       {
                         Console.WriteLine("Async");
                         throw new InvalidOperationException();
                       });
}
like image 542
Ed Pavlov Avatar asked Jun 21 '11 10:06

Ed Pavlov


People also ask

What is assert in NUnit?

The Assert class contains a collection of static methods that implement the most common assertions used in NUnit.

What is assert multiple?

Multiple asserts are good if you are testing more than one property of an object simultaneously. This could happen because you have two or more properties on an object that are related. You should use multiple asserts in this case so that all the tests on that object fail if any one of them fails.


2 Answers

The NUnit test runner executable is configured to ignore exceptions on non-test threads. You can configure this behaviour via app.config configuration element:

legacyUnhandledExceptionPolicy

You can configure non-test threads to cause unhandled exceptions, and so tests will then fail. The caveat is that non-test thread exceptions may be raised whilst another test is running so you may not get an accurate picture of which test failed. Also, as this will be an unhandled exception, test execution will stop at the point the exception happens, rather then continue which is the normal behaviour.

Better than ignoring though in my opinion.

The following article goes into some detail on the topic for the ReSharper test runner, but the principles are the same.

ReSharper test runner – hidden thread exceptions

If you do have multi-threading aspects, from an assertion point of view, I find it better to set flags etc on the non-test thread, wait for the non-test thread to finish, and then assert the state on the test thread. In this way assertion exceptions are raised on the main thread and tests run as expected.

Contrived Example

    [Test]
    public void Test()
    {
        Exception ex = null;

        Action test = () =>
        {
            Console.WriteLine("Async");

            ex = new InvalidOperationException();
        };

        test.BeginInvoke(test.EndInvoke, null).AsyncWaitHandle.WaitOne();

        Assert.That(ex, Is.Null, "Exception did not happen.");
    }
like image 186
Tim Lloyd Avatar answered Oct 07 '22 18:10

Tim Lloyd


Assert.IsTrue(false);

Will throw an exception before the DoesNotThrow call. But NUnit does not work over multiple threads. Cross-threads is more integration then UnitTest. In general I would suggest to avoid to expose the threads/tasks from outside and make an inner behaviour of the used object - so that you can mock this behaviour for testing purposes.

like image 26
weismat Avatar answered Oct 07 '22 19:10

weismat