Grofit
Grofit

Reputation: 18465

MSTest ExpectedException failing

I usually use Nunit but in my current project I am using MSTest. Now I have a test which expects an exception but keeps failing, and I do not have any idea as to why.

Here is a simple example I have used to replicate the problem:

[TestMethod, ExpectedException(typeof(ErrorResponseException))]
        public void should_throw_exception()
        {
            throw new ErrorResponseException();
        }

The ErrorResponseException is a class that just inherits from Exception, that is it, anyone know why this is failing, I would expect it to pass.

Upvotes: 14

Views: 5320

Answers (6)

Moritz Schmidt
Moritz Schmidt

Reputation: 2823

I just had the same problem and found another solution. My method to test was async , but I forgot the await keyword infront of the call in my testmethod.

The Test:

    [TestMethod]
    [ExpectedException(typeof(InvalidOperationException))]
    public async Task ShouldDoSomething(){
         // notice the missing await in the next line
         this.testObject.DoSomethingAsync();
    }

The Method to test:

        public async Task<bool> DoSomethingAsync(){
            if(something)
            {
                throw new InvalidOperationException("Error while doing something");
            }
            return false;
        }

When I ran my test like this it failed. But as soon as I change the Test to the following:

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ShouldDoSomething(){
     await this.testObject.DoSomethingAsync();
}

it worked for me.

Upvotes: 3

Orhan
Orhan

Reputation: 691

In Visual Studio 15with dependencies on MSTest.TestAdapter v1.1.18 and MSTest.TestFramework v1.1.18 you could also use

Assert.ThrowsException<ArgumentNullException>(() => MethodThatThrowsArgumentNullException());

Upvotes: 3

Canine Coders
Canine Coders

Reputation: 549

The ExpectedExceptionAttribute is now defined in multiple DLLs and the unit test runner may be expecting to see the attribute from a different DLL to the one your test project is using.

As an example, I created a unit test project in VS2017 and it gets ExpectedException from Microsoft.VisualStudio.TestPlatform.TestFramework V14.0.0.0 - the test passes in the IDE but fails in TeamCity, even if using the VSTest runner on version 2017.

I eventually got it to pass in TeamCity by deleting all references to this DLL in my test projects and replacing them with version 10.0.0.0 of Mirosoft.VisualStudio.QualityTools.UnitTestFramework

Upvotes: 2

Bradley Braithwaite
Bradley Braithwaite

Reputation: 1122

Shameless plug, but I wrote a simple assembly that makes asserting for exceptions and exception messages a little easier and more readable in MSTest using Assert.Throws() syntax. I wrote a blog post with the full details.

Upvotes: 5

deworde
deworde

Reputation: 2789

If you're using MSTest 10.0.1.0.0, ExpectedException doesn't seem to work correctly, use 10.0.0.0.0 instead.

Upvotes: 3

TrueWill
TrueWill

Reputation: 25553

In NUnit, I would avoid ExpectedException and use Assert.Throws (Exception Asserts) instead. It gives you finer-grained control. Otherwise the test will pass if any portion of the test method throws that exception.

In MSTest, you could get the same level of control with the old-school construct:

try
{
    // code that you expect to throw goes here
    Assert.Fail("Expected MyException");
}
catch (MyException ex)
{
    // optionally assert on the message - this can make tests fragile though
}

With this, there's no need for the ExpectedException attribute.

(The concept comes from the book Test-driven Development: A Practical Guide by David Astels.)

Upvotes: 14

Related Questions