模拟框架不抛出异常的原因是什么

What is the reason for mocking frameworks not throwing exceptions

在下面的示例中 FakeItEasy return 0 即使 IThing 成员 GetValue() 尚未定义。我的问题是;为什么 0 return 的值来自未定义的成员调用而不是抛出的异常;是否有一些通用的 mocking/faking/stubbing 框架软件模式规定不能为调用未定义的成员抛出异常?

public interface IThing
{
    int GetValue();
}

public class Thing: IThing
{
    public int GetValue()
    {
        return 1000;
    }
}

    [TestMethod]
    public void Test1()
    {
        var thing= A.Fake<IThing>();
        // A.CallTo(() => thing.GetValue()).Returns(1);
        var val = thing.GetValue(); // Not defined but returns 0 rather than throwing an exeption
        Assert.AreEqual(1, val);
    }

这主要是一个基于意见的问题,可能会被关闭。但是,这里有一些信息。 首先,有些框架默认是严格的,有些则允许更宽松的语义。 FakeItEasy 倾向于后者。给出这种选择的原因通常是这样的风格支持不那么脆弱的测试——因为用户不必定义与假对象(或模拟,或任何你想称呼它的东西)的每一次交互,当 "unimportant"事情变了,你的测试不会中断 "for no reason".

有些人喜欢严格语义,有些人不喜欢。

请注意,如果您想要 严格的行为,您可以使用 strict fakes

在 FakeItEasy 中获得它
var thing= A.Fake<IThing>(options => options.Strict());

并在 FakeItEasy 2.0.0-rc1, you can use implicit creation options 中通过实现这样的选项生成器来全局启用此行为:

class MakeEverythingStrictOptionsBuilder : IFakeOptionsBuilder
{
    public bool CanBuildOptionsForFakeOfType(Type type)
    {
        return true;
    }

    public void BuildOptions(Type typeOfFake, IFakeOptions options)
    {
        options.Strict();
    }

    public Priority Priority
    {
        get { return Priority.Default; }
    }
}