所以基本上,我有一个抽象类,它有一个唯一的增量 ID - Primitive
.当一个 Primitive
(或更准确地说,Primitive
的继承者)被实例化,ID 递增 - 直到 ID 溢出的点 - 在这一点上,我向异常添加一条消息并重新抛出。
好的,一切都很好......但我正在尝试测试这个功能,我以前从未使用过模拟。我只需要制作足够的 Primitives 以使 ID 溢出并断言它在正确的时间抛出。
Moq
。)这是我的测试(
xUnit
):[Fact(DisplayName = "Test Primitive count limit")]
public void TestPrimitiveCountLimit()
{
Assert.Throws(typeof(OverflowException), delegate()
{
for (; ; )
{
var mock = new Mock<Primitive>();
}
});
}
和:
public abstract class Primitive
{
internal int Id { get; private set; }
private static int? _previousId;
protected Primitive()
{
try
{
_previousId = Id = checked (++_previousId) ?? 0;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
}
我认为我做错了 - 那么我该如何正确测试呢?
最佳答案
你不需要为此 mock 。 当两个类一起工作并且你想用一个模拟(假的)类替换一个类时,你使用模拟,所以你只需要测试另一个类。在您的示例中不是这种情况。
但是,有一种方法可以使用模拟,并且可以解决 2bln 实例的问题。 如果您将 ID 生成与 Primitive
分开类并使用生成器,您可以模拟生成器。一个例子:
我已更改 Primitive
使用提供的生成器。在这种情况下,它被设置为一个静态变量,并且有更好的方法,但作为一个例子:
public abstract class Primitive
{
internal static IPrimitiveIDGenerator Generator;
protected Primitive()
{
Id = Generator.GetNext();
}
internal int Id { get; private set; }
}
public interface IPrimitiveIDGenerator
{
int GetNext();
}
public class PrimitiveIDGenerator : IPrimitiveIDGenerator
{
private int? _previousId;
public int GetNext()
{
try
{
_previousId = checked(++_previousId) ?? 0;
return _previousId.Value;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
}
然后,您的测试用例变为:
[Fact(DisplayName = "Test Primitive count limit")]
public void TestPrimitiveCountLimit()
{
Assert.Throws(typeof(OverflowException), delegate()
{
var generator = new PrimitiveIDGenerator();
for (; ; )
{
generator.GetNext();
}
});
}
这将运行得更快,现在您只测试 ID 生成器是否工作。
现在,当你例如想要测试创建新原语实际上是否需要 ID,您可以尝试以下操作:
public void Does_primitive_ask_for_an_ID()
{
var generator = new Mock<IPrimitiveIDGenerator>();
// Set the expectations on the mock so that it checks that
// GetNext is called. How depends on what mock framework you're using.
Primitive.Generator = generator;
new ChildOfPrimitive();
}
现在您已经分离了不同的关注点并可以分别测试它们。
关于c# - 对这个单元测试感到困惑!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4117894/