A place for spare thoughts

17/05/2011

MSTest and SEHException

Filed under: Unit testing — Ivan Danilov @ 18:10

Corporate standards sometimes are evil thing, you know. And so on one of my work projects I’m forced to use MSTest.

So today I’ll describe the history of one problem I faced with Microsoft testing framework.

So, I’ve been writing some unit tests happily when strange message from next test run made me crazy:
‘Test method Test threw exception:  System.Runtime.InteropServices.SEHException: External component has thrown an exception..’

Without any clues what is the cause. Googling on the problem gave only not very helpful complaint about the same problem. After some time of trials I was able to narrow problematic case to the following:

[TestClass]
public class FailingTest
{
    [TestMethod]
    public void Test()
    {
        var mocks = new MockRepository();
        var someService = mocks.Stub<ISomeService>();
        someService.Expect(s => s.Method()).IgnoreArguments().Return(null);
    }
}

ISomeService is some interface from third-party vendor placed in it’s own assembly (let it be ‘Interface.dll’ for convenience) referenced from test project. MockRepository is part of Rhino Mocks (I’m just too lazy to rewrite code again without it, the problem is not specific to Rhino Mocks in any way).

But could it be some my error? I decided to check — referenced nunit.famework.dll, replaced [TestClass] with [TestFixture], [TestMethod] with [Test] and run. Success was the result. Well, something wrong with MSTest not my test code.

Maybe problem is within VS test runner? But ReSharper runner and VS integrated runner shows the same… Nevertheless I tried mstest.exe command line also. Same failure. Hmm…

It turned out that MSTest saw that Interface.dll has reference to some other assembly, Other.dll and tried to load it when testing. Why does it do such thing is mystery, but it does. If you put Other.dll to references of our test project – test will succeed. If you have no reference and no Other.dll accessible to the test – you’ll have adequate error message about MSTest can’t load required assembly named Other.dll. But (the most frustrating case!) if you have no reference to Other.dll but have it accessible (for example placed in the bin\Debug of test project) — you’ll have that terrible SEHException without any information.

The scenario is not as theoretic as you could think. Imagine TFS build server (God save us from it). With default settings it will put every resulting artifact (compiled assemblies, debug symbols, referenced assemblies that have Copy local=true etc) to the same Binaries folder. And if you have complex solution where Other.dll is actually used somewhere – it gets copied to Binaries. And if test project doesn’t have reference – you’ll have SEHException. Ghrrrr!

Advertisements

1 Comment »

  1. Tks you so much…. I will open a party for this problem.

    Comment by kiemchung — 05/09/2012 @ 09:54


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: