我可以创建一个符合接口的模拟器,并且还知道其基类上的方法吗?

时间:2017-03-04 06:26:00

标签: c# winforms unit-testing mocking moq

我正在使用Moq在WinForms应用中测试演示者。主持人有一个观点。该视图符合ISomeControl,并继承自UserControl

在测试此演示者时,我想测试调用View上的Show()方法。

所以我创建了一个这样的模拟:

var someControl = new Mock<ISomeControl>();

但问题出在这里:在我的应用程序中,有一个地方可以将ISomeControl转换为Control,以便我可以调用基类Show()。因为Mock只知道它是ISomeControl,所以我得到以下错误:

  

无法将类型为“Castle.Proxies.ObjectProxy_1”的对象强制转换为类型   'System.Windows.Forms.Control的'。

有解决方法吗?

2 个答案:

答案 0 :(得分:2)

创建一个基础抽象类,它继承ISomeControlUserControl,以便在单元测试中进行模拟。

public abstract class SomeDummyControl : UserControl, ISomeControl { 
    //...
}

这应该允许mock知道这两种类型。

var mock = new Mock<SomeDummyControl>();
//...arrange setup

var dummyControl = mock.Object;
//...pass the dummy as a dependency

//just to show that it should be able to cast
var control = dummyControl as Control;
var someControl = dummyControl as ISomeControl;

模拟可以在需要时进行验证

mock.Verify(m => m.Show(), Times.AtLeastOnce()); //verifies that the Show method was called.

在此处阅读有关Moq的更多信息Moq Quickstart

答案 1 :(得分:1)

可以使用模拟来实现多个接口

Moq Quick Start的摘录显示了如何执行此操作:

// implementing multiple interfaces in mock
var foo = new Mock<IFoo>();
var disposableFoo = foo.As<IDisposable>();
// now the IFoo mock also implements IDisposable :)
disposableFoo.Setup(df => df.Dispose());

//implementing multiple interfaces in single mock
var foo = new Mock<IFoo>();
foo.Setup(f => f.Bar()).Returns("Hello World");
foo.As<IDisposable>().Setup(df => df.Dispose());