I want to be able to run the same test with multiple implementations of a dependency.
The normal way to do what I want is the following:
[Theory]
[InlineData(DoerType.Version1)]
[InlineData(DoerType.Version2)]
public void DoSomethingTest(DoerType type)
{
IDoSomething doer = Factory.Create(type);
string result = doer.DoSomething();
}
Here's an alternate impl where I've shifted the call to the Factory Method out into a custom attribute:
[Theory]
[DoerVersions(DoerType.Version1, DoerType.Version2)]
public void DoSomethingTest(IDoSomething doer)
{
string result = doer.DoSomething();
}
public class DoerVersionsAttribute : DataAttribute
{
private readonly DoerType[] doers;
public DoerVersionsAttribute(params DoerType[] doers)
{
this.doers = doers;
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
return doers.Select(d => new object[] { Factory.Create(d) });
}
}
But given the large amount of tests that I want to do with this, I'm looking for a clean and as-DRY-as-possible way to do it.
Is there a way to avoid the parameter altogether and, for example, set the implementation on the test class field (or its base class)?
public class Tests
{
private IDoSomething Doer;
[Theory]
[DoerVersions(DoerType.Version1,DoerType.Version2)]
public void DoSomethingTest()
{
string result = Doer.DoSomething();
}
}
Other ways of expressing the same intent could be acceptable too.
Edit: why do I want this?
I didn't include this in the original question to avoid discussions about my motives.
I want to be able to write tests with as little technical information as possible and then run them through different "interfaces". For example (this is still an approximation):
[Theory]
[Interfaces(Interface.WebChrome, Interface.WebFirefox, Interface.Android)]
public void ShouldBeAbleToSearchBook()
{
dsl.Users.Login("user1");
dsl.Searcher.Search("title:BDD");
dsl.Searcher.ShouldHaveResult("Some BDD book");
}
So, having parameters and factories on each test would add considerable noise to the information ratio.