Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In MSTest, How can I verify exact error message using [ExpectedException(typeof(ApplicationException))]

Using MSTest how can I verify the exact error message coming from a test method? I know [ExpectedException(typeof(ApplicationException), error msg)] doesn't compare the error message coming from my test method, though in other unit test framework it is doing.

One way to solve this problem is to write my unit test using some try catch block, but again I need to write 4 lines more.

Is there any smartest way to check the error message.

Cheers, Pritam

like image 354
Pritam Karmakar Avatar asked Dec 22 '09 07:12

Pritam Karmakar


3 Answers

You can create your own ExpectedException attribute where you can Assert the message of the Exception that was thrown.

Code

namespace TestProject
{
    public sealed class MyExpectedException : ExpectedExceptionBaseAttribute
    {
        private Type _expectedExceptionType;
        private string _expectedExceptionMessage;

        public MyExpectedException(Type expectedExceptionType)
        {
            _expectedExceptionType = expectedExceptionType;
            _expectedExceptionMessage = string.Empty;
        }

        public MyExpectedException(Type expectedExceptionType, string expectedExceptionMessage)
        {
            _expectedExceptionType = expectedExceptionType;
            _expectedExceptionMessage = expectedExceptionMessage;
        }

        protected override void Verify(Exception exception)
        {
            Assert.IsNotNull(exception);

            Assert.IsInstanceOfType(exception, _expectedExceptionType, "Wrong type of exception was thrown.");

            if(!_expectedExceptionMessage.Length.Equals(0))
            {
                Assert.AreEqual(_expectedExceptionMessage, exception.Message, "Wrong exception message was returned.");
            }
        }
    }
}

Usage

[TestMethod]
[MyExpectedException(typeof(Exception), "Error")]
public void TestMethod()
{
    throw new Exception("Error");
}
like image 70
chaliasos Avatar answered Oct 23 '22 10:10

chaliasos


Use this little helper class:

public static class ExceptionAssert
{
    public static void Throws<TException>(Action action, string message)
        where TException : Exception
    {
        try
        {
            action();

            Assert.Fail("Exception of type {0} expected; got none exception", typeof(TException).Name);
        }
        catch (TException ex)
        {
            Assert.AreEqual(message, ex.Message);
        }
        catch (Exception ex)
        {
            Assert.Fail("Exception of type {0} expected; got exception of type {1}", typeof(TException).Name, ex.GetType().Name);               
        }
    }
}

Usage:

Foo foo = new Foo();
foo.Property = 42;

ExceptionAssert.Throws<InvalidOperationException>(() => foo.DoSomethingCritical(), "You cannot do anything when Property is 42.");

The advantage of explicit catching exceptions is that teh test does not succeed when another member (e.g. during the initialization) throws the exception.

like image 43
Matthias Avatar answered Oct 23 '22 10:10

Matthias


Fluent Assertions (NuGet) has a very "language natural" syntax for defining expectations in unit tests:

objectundertest.Invoking(o => o.MethodUnderTest()).Should().Throw<ExpectedException>()
    .WithMessage("the expected error message");

There are multiple variations for checking the error message with any algorithm (Where(e => ...) as well as checking into inner exceptions and their messages.

like image 8
Marc L. Avatar answered Oct 23 '22 09:10

Marc L.