1

I have several methods that expect an instance of an interface ITable. Now I´m not sure if it is worth the effort of creating a test for this parameter for every method, this seems like a break on DRY.

So I wonder if there is a possibilty to call all those methods within one single test-method and assert that all of them fail for the same reason - in my case an ArgumentException.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • What unit testing framework are you using? – Ant P Aug 04 '15 at 13:33
  • The Visual-Studio NUnit-extension – MakePeaceGreatAgain Aug 04 '15 at 13:34
  • XUnit or NUnit have test parameters for this purpose, I'm sure there are other testing frameworks that do too. – Ron Beyer Aug 04 '15 at 13:34
  • @HimBromBeere here's the answer: http://stackoverflow.com/questions/1609536/nunit-assert-throws – Sergey Kolodiy Aug 04 '15 at 13:35
  • @SergeyKolodiy There is no `Assert.Throws` within VS integrated NUnit-framework – MakePeaceGreatAgain Aug 04 '15 at 13:40
  • @HimBromBeere that's strange, we are using NUnit and I see lots of `Assert.Throws(...)` in our tests. Make sure you are not confusing NUnit with MSTest, which has an attribute for that. – Sergey Kolodiy Aug 04 '15 at 13:46
  • [Yes there is](http://www.nunit.org/index.php?p=exceptionAsserts&r=2.5) – Jon Hanna Aug 04 '15 at 15:18
  • @JonHanna To avoid further confudion: I´m using this VS-extension for the tests https://visualstudiogallery.msdn.microsoft.com/c8164c71-0836-4471-80ce-633383031099. And there is no `Assert.Throws` but an attribute called `ExpectedException`. However the question is on setting ALL calls to expect that specific exception. – MakePeaceGreatAgain Aug 05 '15 at 07:10
  • Does that extension work if you pull in a current version of NUnit through Nuget? It'd be easier to use `Assert.Throws` for this, and then you'd have it. – Jon Hanna Aug 05 '15 at 08:50

2 Answers2

1

You can use AutoFixture.Idioms for that, although by default it'll test for ArgumentNullException because null is really the only invalid value for an interface.

You can write something like this to check all members for invalid values (including members that take ITable as an argument):

var fixture = new Fixture();
var assertion = new GuardClauseAssertion(fixture);
assertion.Verify(typeof(MyType));

The Verify call will throw an exception if it passing null as an argument doesn't throw an ArgumentNullException.

There are lots of options for narrowing down the selection. As an example, there's a Verify overload that takes IEnumerable<MemberInfo>, so you can use Reflection to query your type for all members that have an ITable argument.

If you need specific help with AutoFixture or AutoFixture.Idioms, please ask a new question and tag it autofixture, as it can become a bit tiresome answering complex questions in the comments :)

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
0

I think I have a solution, it´s not nice but it does its work. For that I simply loop all the methods within the type to test and check if there is any parameter within the methods list that implements the interface:

var funcs = typeof(MyType).GetMethods().Where(x => x.GetParameters().Any(y => typeof(ITable).IsAssignableFrom(y.ParameterType)));

Now I can loop this collection and call its methods via reflection. Finally I just count how often an eception of type ArgumentException has been thrown by incrementing a counter when the exception is hit:

foreach (var func in funcs)
{
    try {func.Invoke(myInstance, myArgs);}
    catch(ArgumentException) { i++; }
}

If the counter is equal to the number of methods found the test is successfull:

Assert.AreEqual(i, expectedCount);
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • Writing the code in this manner will make it extremely difficult to track and analyse failures; I'd strongly recommend looking into `AutoFixture.Idioms` as alluded to in Mark's answer assuming you have any interesting quantity of these kinds of requirements as it really is made for the job. – Ruben Bartelink Aug 20 '15 at 16:10