FakeItEasy 属性 getter 调用规则未触发

FakeItEasy property getter call rule not triggered

我正在尝试让 FakeItEasy 1.25.3 在 属性 上抛出异常; setter 测试工作正常,但 getter 没有按预期抛出异常。我究竟做错了什么?

public interface IMisc
{
    int IntProperty { get; set; }
}

// Setter throws exception as expected.
[Test]
public void Property_Setter_Throws()
{
    var driver = A.Fake<IMisc>();
    A.CallTo(driver).Where(call => call.Method.Name == "set_IntProperty")
          .Throws(new Exception());
    var i = driver.IntProperty; 
    Assert.That( delegate { driver.IntProperty = 3; }, Throws.Exception);
}

// Getter does not throw exception as expected.
[Test]
public void Property_Getter_Throws()
{
    var driver = A.Fake<IMisc>();
    A.CallTo(driver).Where(call => call.Method.Name == "get_IntProperty")
          .Throws(new Exception());
    driver.IntProperty = 3;
    Assert.That(delegate { var i = driver.IntProperty; }, Throws.Exception);
}

就是这一行:

driver.IntProperty = 3;

这就是您遇到问题的原因。它所做的基本上是在调用时将 getter 配置为 return 值 3。

这是因为 IntProperty 是 Read/Write 属性。有关详细信息,请参阅 this

引自上文link:

Although you can explicitly specify the return value for a called property getter, there's an easier, more intuitive way to work with read/write properties. By default, any fakeable property that has both a set and get accessor behaves like you might expect. Setting a value and then getting the value returns the value that was set.

此外,请注意,由于修复了 FakeItEasy 2.0,您看到的行为将发生变化 magic property get followed by another get returns different object when property type is not fakeable。 有了这个改变,你的两个测试将以大致相同的方式失败 - Property_Setter_Throws 也会失败,因为使用 getter 作为 driver.IntProperty 将使 FakeItEasy 成为 return将来相同的 return 值实例(它正在设置自动 属性 规则)。

作为将来可能对您有所帮助的更多信息,您可能会喜欢使用类型安全方法来设置 属性 行为:

A.CallTo(driver).Where(call => call.Method.Name == "get_IntProperty")
                .Throws(new Exception());

可以变成

A.CallTo(() => driver.IntProperty).Throws(new Exception());

(在 FakeItEasy 2.0 中,有 a similar method for configuring 属性 设置器):

A.CallToSet(() => driver.IntProperty).Throws(new Exception());