【发布时间】:2017-05-18 12:47:18
【问题描述】:
我想将用于测试接口行为本身的单元测试与实现的附加业务行为分开。
public interface IIncrementor
{
void Increment();
int Count { get; }
}
public class AIncrementor : IIncrementor { /* Implementation */ }
public class BIncrementor : IIncrementor { /* Implementation */ }
为了确保接口业务行为的正确性,我需要根据我定义的单元测试检查所有相应的实现。当然,每个实现都有自己的额外行为要测试,但我不想一遍又一遍地重复自己。
我当前的解决方案是创建一个带有抽象属性的抽象测试类,供子类实现。
public abstract class IIncrementorTest
{
protected abstract IIncrementor Incrementor { get; }
[Fact]
public void WhenIncremented_ThenCounterHasCorrectValue()
{
var oldCount = Incrementor.Count;
Incrementor.Increment();
Assert.Equal(oldCount + 1, Incrementor.Count);
}
}
public class AIncremetorTest : IIncrementorTest
{
protected override IIncrementor Incrementor => new AIncrementor();
[Fact]
public void WhenSomeAdditional_ThenCheckSomething() { /* More test */ }
}
public class BIncremetorTest : IIncrementorTest
{
protected override IIncrementor Incrementor => new BIncrementor();
[Fact]
public void WhenSomeAdditional_ThenCheckSomething() { /* More test */ }
}
但这会导致一些问题,例如当一个测试用例需要以不同的方式构建一个实例时,这很可能会发生。您是否建议为这些情况创建抽象属性?
protected abstract IIncrementor IncrementorForCheckingSomething { get; }
或者是否有一个最佳实践方法可以全面解决这个接口测试问题?
【问题讨论】:
-
你为什么要测试一个模拟?
-
这个问题不清楚。
-
@Nkosi 我想根据单元测试检查接口的所有实现;如果我的业务规则暗示商店中的商品数量必须增加,因为我调用 Save-method 我想在接口“本身”上测试这种行为,这意味着我必须收集所有实现类反射方式(模拟) 并让他们通过单元测试。
-
不清楚的是
mock the implementation-types。那些不会是模拟,它们将是实现实例。只需使用反射并获取所有实现并为每个实现创建一个实例来运行您的测试。另外这个问题有点宽泛,因为没有迹象表明实现是否具有也需要模拟的依赖项。
标签: c# unit-testing mocking moq xunit