简体   繁体   English

犀牛模拟接口IA,该接口使用抽象类aB实现接口IB

[英]rhino mock an interface IA which implements interface IB with abstract class aB

I have a situation where I have in interface 我在界面中遇到的情况

public interface IA : IB
{
}

where 哪里

public interface IB
{
    List<string> Errors{get;}
    void AddError(string error);
}

with an abstract class 与抽象类

public abstract class B
{
    private List<string> errors = new List<string>();
    public List<string> Errors{get{return errors;}}
    public void AddError(string error)
    {
        if (!errors.Contains(error)) 
            errors.Add(error);
    }        
}

And I have a method on another class like: 我在另一个类上有一个方法:

public class MyClass
{
    public void MyMethod(IA obj)
    {            
        obj.AddError("some string");
    }
}

then I have a unit test where I would like to test that MyClass does what it is supposed to by passing in a stubbed IA: 然后我有一个单元测试,我想通过传递存根的IA来测试MyClass是否达到了预期的目的:

public void Test()
{
    var sut = new MyClass();
    var input = MockRepository.GenerateStub<IA>();
    sut.MyMethod(input);
    Assert.AreEqual(1, input.Errors.Count);
}

but when it comes to the assertion, Errors is null as the base class B is not included in the stub for IA, is there any way to specify that I want the implementation of IB to be provided by an abtsract class without having to create a concrete class that derives from B? 但是谈到断言时,由于IA的存根中不包含基类B,所以Errors为null,有什么方法可以指定我希望abtsract类提供IB的实现,而不必创建一个从B派生的具体类别?

I have missed some of the detail from this, but I will expand by saying that there are a set of interfaces like IA all implementing IB, and a set of classes like MyClass each taking a different interface and the detail of MyMethod depends on the interface IA that it accepts, but the interfaction with the implementation of IB is always the same. 我错过了其中的一些细节,但是我会继续扩展说,有一组接口(如IA都实现了IB),还有一组类(如MyClass)都采用了不同的接口,而MyMethod的细节取决于该接口它接受IA,但是与IB实施的相互作用始终是相同的。

One possible solution is to create an abstract implementation of IA 一种可能的解决方案是创建IA的抽象实现

public abstract class A : B, IA
{
    //abstract implementations of all properties and methods on IA, nothing concrete
}

this can then be stubbed in the unit test: 然后可以将其存入单元测试中:

public void Test()
{
    var sut = new MyClass();
    var input = MockRepository.GenerateStub<A>();
    sut.MyMethod(input);
    Assert.AreEqual(1, input.Errors.Count);
}

and the propertis and methods on A that need to be stubbed (or mocked) can than be done. 然后就可以对A上的属性和方法进行存根(或嘲笑)。

It does mean that an additional class nedds to be wiritten fr each interface that exists in the vein of IA, whic is far from ideal, but its the nly way I see around this for now. 这确实意味着要在IA静脉中存在的每个接口中编写额外的类nedds,虽然这远非理想,但是我现在才看到这是一种巧妙的方法。

Interface stands for behavioral contract. 接口代表行为契约。 It is by its nature not coupled with any implementation. 从本质上讲,它没有任何实现。 What you want is a mock-ed object who carries behavior defined by class B (in other words you need a mocked B object), and at the same time implements IA. 您想要的是一个模拟对象,该对象具有由类B定义的行为(换句话说,您需要一个模拟的B对象),同时实现IA。

You could use multi, partial mock to achieve it: 您可以使用多个部分模拟来实现它:

var sut = new MyClass();
var input = MockRepository.GeneratePartialMock<B, IA>();
sut.MyMethod((IA)input);
Assert.AreEqual(1, input.Errors.Count);

GeneratePartialMock is the method to mock a class who already has some behavior defined. GeneratePartialMock是模拟已经定义了某些行为的类的方法。 Basically it gives you the capability to rewrite(stub) override-able methods defined in a class. 基本上,它使您能够重写(存根)类中定义的可重写方法。 And if you don't stub a method, the original behavior will be invoked. 而且,如果您不存根方法,则将调用原始行为。

You can include more interfaces (in your case, IA) in the type parameter list to dynamically add behavior to your mock-ed object. 您可以在类型参数列表中包括更多接口(以您的情况为IA),以将行为动态添加到模拟对象。

Note you have to revise the code you posted in order to make it work: 请注意,您必须修改发布的代码才能使其正常工作:

  1. Initialize () should be defined in the interface IB Initialize()应该在接口IB中定义
  2. Methods should be defined as virtual in class B 方法应在B类中定义为虚拟

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM