【问题标题】:Mock is operator模拟是运算符
【发布时间】:2013-04-15 13:11:04
【问题描述】:

是否可以模拟 is 运算符?在我的代码中,我的逻辑取决于它是什么类型的类,但值本身作为公共接口存储在类中。

基本上,我想做的是通过将模拟定义为IValue 来返回true,但为is Value 返回true

public class Value : IValue
{
}

public interface IValue
{
}
public class Tester
{
    public bool CheckIfValue(IValue value)
    {
        return value is Value;
    }
}

[Test]
public void TestIfValue()
{
    Tester tester = new Tester();

    var value = MockRepository.GenerateStub<IValue>();
    // can I add anything here which will make CheckIfValue return true?

    bool isValue = tester.CheckIfValue(value);
    Assert.That(isValue, Is.True);
}

【问题讨论】:

  • MockRepository.GenerateStub&lt;IValue&gt;() 返回不是ValueIValue 实现吗?
  • @ken2k - 是的,它将在运行时创建一个使用 Castle.DynamicProxy 框架实现该接口的类。

标签: c# unit-testing generics rhino-mocks


【解决方案1】:

不,不可能“模拟”is 运算符,is 在以下情况下只会返回 true:

  1. 被检查的对象是被检查类型的一个实例。
  2. 被检查的对象是被检查类型的子类。
  3. 被检查的对象实现了被检查的接口类型。

你的设计很糟糕,如果你真的需要 IValue 作为 Value 的实例,你不应该要求它。

关键是依赖于抽象而不是实现,这就是为什么你有IValue 接口开始的原因。 Tester 不应该关心它是否得到 ValueMockValue 或其他任何东西,它应该只依赖于 IValue 接口中定义的方法和属性。

创建模拟的重点是在特定场景下测试 Tester 类的行为,模拟允许您指定 Tester 为该测试接收的对象的行为,而无需创建大量虚拟对象class FakeValueWhichDoes... : IValue 之类的类,以便对其进行测试。

【讨论】:

  • +1,同意糟糕的设计。接口的全部目的是不使用实际的实现。如果参数是 IValue 类型,那么整个代码块应该只使用 IValue 公开的内容。
  • 您的三个案例不完整,仅供参考。例如,object o = (Func&lt;string&gt;)(()=&gt;""); bool b = o is Func&lt;object&gt;; 结果为真,但不满足您的三种情况中的任何一种。
  • @EricLippert 感谢您指出这一点,我忘了提及协方差。
  • 如果你有int? x = 123; bool b = x is int; int 怎么办?不是 int,不是 int 的子类型,没有检查接口,也没有涉及协方差,但 b 仍然为真。所以你在这里错过了第五个案例。
【解决方案2】:
public class Value : IValue
{
    bool Is<T>() => this is T;
}

public interface IValue
{
    bool Is<T>();
}

public class Tester
{
    public bool CheckIfValue(IValue value)
    {
        return value.Is<Value>();
    }
}

[Test]
public void TestIfValue()
{
    Tester tester = new Tester();

    var value = MockRepository.GenerateStub<IValue>();
    value.Stub(_ => _.Is<Value>()).Return(true);

    bool isValue = tester.CheckIfValue(value);
    Assert.That(isValue, Is.True);
}

【讨论】:

    猜你喜欢
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    相关资源
    最近更新 更多