1

Is there a way to write that I'm expecting a certain exception for certain inputs when I use the Factory attribute? I know how to do it using the Row attribute but I need it for dynamically generated test inputs.

See test example bellow for a function that returns the inverse of the provided string:

[TestFixture]
public class MyTestFixture()
{
   private IEnumerable<object[]> TestData
   {
      get
      {
          yield return new object[] { "MyWord", "droWyM" };
          yield return new object[] { null, null }; // Expected argument exception
          yield return new object[] { "", "" };
          yield return new object[] { "123", "321" };
      }
   }

   [Test, Factory("TestData")]
   public void MyTestMethod(string input, string expectedResult)
   {
      // Test logic here...   
   }
}
Butcher
  • 395
  • 1
  • 3
  • 4
  • Avoid ExpectedException. Use Assert.Throws if it supports it; otherwise see the pattern discussed at http://lostechies.com/jimmybogard/2008/03/11/the-many-faces-of-expectedexception/ – TrueWill Aug 01 '11 at 18:11
  • @TrueWill. I disagree with a such dogmatic approach. It's true that Assert.Throw is more accurate and ensures that the exact expected portion of code is actually throwing the exception, but there is simple test cases where the use of an [ExceptionException] attribute is still better, especially in terms of readability; typically when you test for invalid constructor or method arguments. – Yann Trevin Aug 01 '11 at 19:46
  • @Yann - James Newkirk has also come out against ExpectedException: http://jamesnewkirk.typepad.com/posts/2008/06/replacing-expec.html Personally I never use it in new test code. – TrueWill Aug 02 '11 at 02:10

1 Answers1

0

I'm afraid that there is no built-in functionality to attach metadata (such as an expected exception) to a row of test parameters coming from a factory method.

However, a simple solution is to pass the type of the expected exception as a test regular parameter (null if no exception is expected to be thrown) and to enclose the tested code in an Assert.Throws or Assert.DoesNotThrow method.

[TestFixture]
public class MyTestFixture()
{
  private IEnumerable<object[]> TestData
  {
    get
    {
        yield return new object[] { "MyWord", "droWyM", null };
        yield return new object[] { null, null, typeof(ArgumentNullException) };
        yield return new object[] { "", "", null };
        yield return new object[] { "123", "321", null };
    }
  }

  [Test, Factory("TestData")]
  public void MyTestMethod(string input, string expectedResult, Type expectedException)
  {
    RunWithPossibleExpectedException(expectedException, () => 
    {
       // Test logic here... 
    });
  }

  private void RunWithPossibleExpectedException(Type expectedException, Action action)
  {
    if (expectedException == null)
      Assert.DoesNotThrow(action);
    else
      Assert.Throws(expectedException, action);
  }
}

By the way, it could be interesting to have an extra Assert.MayThrow assertion to get rid of the helper method. It could just accept null as the expected exception type. Maybe you could create a feature request here, or you may submit a patch.

Yann Trevin
  • 3,823
  • 1
  • 30
  • 32