使用xUnit.net什么是干净的(可读/可理解的和可维护的)方法,为同一个接口的多个实现重用相同的测试?
act 和断言部分测试总是相同的(因为接口的所有实现都应该表现相同)。对于每次测试运行,SUT都是不同的,对于某些特定测试,排列部分略有不同。
例如,我有以下接口的多个实现(MemoryRepository
,FileReposity
...)。
interface IRepository
{
object GetById(string id);
void Set(string id, object value);
}
现在我的测试应该确保所有实现都表现相同:
// all implementations of IRepository must behave like this
// so do this test for all implementations
[Fact]
public void GetRetrievesWhatWasPut()
{
IRepository sut = new MemoryRepository();
sut.Set("key", 10);
var result = sut.Get("key");
result.Should().Be(10);
}
答案 0 :(得分:5)
您可以考虑撰写test classes as generic classes:
public abstract class IntervalFacts<T>
{
[Theory, AutoCatalogData]
public void MinimumIsCorrect(IComparable<T> first,
IComparable<T> second)
{
var sut = new Interval<T>(first, second);
IComparable<T> result = sut.Minimum;
Assert.Equal(result, first);
}
}
public class DecimalIntervalFacts : IntervalFacts<decimal> { }
public class StringIntervalFacts : IntervalFacts<string> { }
public class DateTimeIntervalFacts : IntervalFacts<DateTime> { }
public class TimSpanIntervalFacts : IntervalFacts<TimeSpan> { }
这个特例利用AutoFixture组合具体类的能力,这样可以省去实例化每个T
的具体实例的麻烦。
改变排列阶段更加困难,但根据您需要做的事情,您可以再次向AutoFixture引入一些约定,以便它根据类型自动更改创建的实例。
对于OP中的类型,您可以编写如下测试:
public abstract class RepositoryFacts<T> where T : IRepository
{
[Theory, AutoRepositoryData]
public void GetRetrievesWhatWasPut(T sut)
{
sut.Set("key", 10);
var result = sut.Get("key");
result.Should().Be(10);
}
}
public class MemoryRepositoryFacts : RepositoryFacts<MemoryRepository> { }
public class FileReposityRepositoryFacts : RepositoryFacts<FileReposity> { }
答案 1 :(得分:0)
您可以通过使用诸如GetThingToBeTested()之类的抽象方法来测试多个工具。
public abstract class Tester
{
public abstract Func<string, string, bool> GetThingToBeTested();
[Theory]
[InlineData("carrot", "tarroc")]
[InlineData("apple", "papel")]
public void Will_be_a_permutation(string original, string valueToTest)
{
GetThingToBeTested()(original, valueToTest).Should().BeTrue();
}
[Theory]
[InlineData("hello", "llloh")]
public void Will_not_be_a_permutation(string original, string valueToTest)
{
GetThingToBeTested()(original, valueToTest).Should().BeFalse();
}
}
public class Sort : Tester
{
public override Func<string, string, bool> GetThingToBeTested()
{
return IsPermutation_Sort;
}
}
public class Count : Tester
{
public override Func<string, string, bool> GetThingToBeTested()
{
return IsPermutation_Count;
}
}