chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
I am running into a NullReferenceException when trying to validate a method in an abstract class that aborts a background thread. I want to verify that, in addition to other things that happen in the method, the background thread is aborted. This sample code is a simplified version of the real code that focuses on aborting the thread.

    public abstract class Foo
        public static void KillTime()
                for (int i = 0; i < 10000000; i++)

        public Thread MyThread { get; set; }

        public void StartThread()
            MyThread = new Thread(new ThreadStart(RunStuff));
            MyThread.Name = "Thread RunStuff";

        public void AbortThread()

        public void RunStuff()

Here is the unit test that is a simplified form of my actual unit test.

        public void AbortThreadTest()
            Foo fakeFoo = Isolate.Fake.Instance<Foo>(Members.CallOriginal);

            //Isolate.WhenCalled(() => fakeFoo.RunStuff()).DoInstead(context => Foo.KillTime());


            Assert.AreEqual<ThreadState>(ThreadState.AbortRequested | ThreadState.WaitSleepJoin, fakeFoo.MyThread.ThreadState,
                "The thread has not been aborted");

            Assert.IsTrue(fakeFoo.MyThread.Join(500), "The thread did not finish aborting in time");

As listed above, the unit test above passes. This indicates that the KillTime method is not a problem. However, if the commented line is uncommented (as in the real unit test), then the test is aborted and the test run reports the following error:

One of the background threads threw exception: System.NullReferenceException: Object reference not set to an instance of an object.
at du.Invoke(Object[] A_0, Object A_1)
at ad.a(DynamicReturnValue A_0, Object A_1, Object[] A_2, Object A_3)
at ad.a(DynamicReturnValue A_0, Object A_1, Object[] A_2, Type A_3, Object A_4)
at ad.a(Object A_0, Object[] A_1, Type A_2, Scope A_3, Int32 A_4, Object A_5, Type A_6)
at bi.a(String A_0, Object[] A_1, Object A_2, Object A_3, String A_4, Type A_5)
at b2.a(String A_0, Object A_1, MethodBase A_2, Object[] A_3, Object A_4, String A_5, bi A_6)
at b2.b(Object A_0, String A_1, String A_2, MethodBase A_3, Object[] A_4, Object A_5)
   at TypeMock.MockManager.a(String A_0, String A_1, Object A_2, Object A_3, Boolean A_4, Object[] A_5)
   at TypeMock.InternalMockManager.getReturn(Object that, String typeName, String methodName, Object methodParameters, Boolean isInjected)
   at TestProject1.Foo.RunStuff() in ...TestProject1UnitTest1.cs:line 115
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
Test host process exited unexpectedly.

If I comment the last Assert out that does the Join, then the test passes, but I still get a test run error that only reports the last line in the error above: "Test host process exited unexpectedly."

The actual RunStuff method is private in my abstract class; making it public (like in the code above) did not make a difference.

Also, I tried making the Foo class above a concrete class (unlike my actual class which is abstract - hence, the need to create a fake instance) and still encountered the same problems. However, if I made Foo a concrete class and created a real instance (avoiding Isolator altogether), then the test passed and the test run did not report any errors.

I am looking for any ideas as to what is wrong with the test or suggestions on alternate approaches to testing that the thread gets aborted.

asked by bhunter (3.4k points)

2 Answers

0 votes

According to the stack trace it seems like somewhere between threads the dynamic behavior delegate supplied to DoInstead() lost its calling context, which causes it to throw a null reference exception from its inner invocation. I will need to work a bit further to get a local repro of this issue and debug it to find out the root cause. I will post my findings here then.

Typemock Support
answered by doron (17.2k points)
0 votes
I was just wondering if any progress had been made on this issue.

I actually just ran into it again on another unit test where I am validating the actions taking when the background thread is aborted. Within the DoInstead, I am aborting the current thread to cause the ThreadAbortException to be thrown. I would have used WillThrow, but ThreadAbortException does not have any public constructors. However, I did find a workaround by aborting the unit test thread, catching the ThreadAbortException, getting a reference to the exception object, calling Thread.ResetAbort to stop the abort, and finally passing the reference to WillThrow.

answered by bhunter (3.4k points)