tags:

views:

45

answers:

2

Hi, I have various objects in application,and each has isvalid method to test if values of all properties are set correctly(as per business rules).Now,to test that for each violation isvalid throws false,i will have to write as many tests as rules being checked in isvalid.Is there a simpler way to do this? I am using MBunit.

A: 

You may want to consider whether the perceived need for duplicating the test effort doesn't indicate code duplication in your SUT.

Perhaps you could implement the business rules as a Strategy, in which case you only need to test the Strategy implementation once, and then for each SUT verify that they use the correct Strategy.

Otherwise, a set of Parameterized Tests sounds like the way to go.

Mark Seemann
+1  A: 

I'm not sure what you'd want to be simpler. You may want to create a helper method to create a a valid object to start with, so that each test is something like:

public void FooWithNullNameIsInvalid()
{
    Foo foo = CreateValidFoo();
    foo.Name = null;
    Assert.IsFalse(foo.IsValid);
}

Then each test is relatively small, tests one thing, and is easy to understand. Yes, this sort of thing can be somewhat monotonous, but it works.

Another alternative to make the tests even shorter would be:

private void AssertInvalidChange(Action<Foo> change)
{
    Foo foo = CreateValidFoo();
    change(foo);
    Assert.IsFalse(foo.IsValid);
}

Then each test can just be of the form:

public void FooWithNullNameIsInvalid()
{
    AssertInvalidChange(foo => foo.Name = null);
}

Now at that stage you could put all the validity tests in a single method, with one line per invalid change. That would certainly be simpler, but it would violate the "only test one thing" mantra. Personally I'm fairly loose with that - I would be fairly strongly tempted to do this. The downside is that if you have multiple tests that would fail, you'll only see one failure at a time.

Jon Skeet
interesting idea indeed!
jess