Во-первых, вы можете создавать заглушки / макеты классов непосредственно в RhinoMock, поэтому, если вы хотите использовать настоящую заглушку CallMonitor, а не ICallMonitor, это поможет вам решить проблему с приведением в вашем коде. Причина сбоя приведения заключается в том, что RhinoMock создает объект «динамический прокси», который не является CallMonitor.
Во-вторых, вы не можете смоделировать вызовы конструктора, и что наиболее важно, нет способа смоделировать вызов нового CallMonitor в конструкторе DeviceMediator, поскольку нет способа внедрить экземпляр.
Обычным способом сделать то, что вы хотите, было бы изменить конструктор DeviceMediator следующим образом:
public DeviceMediator(IDeviceControlForm form, IDataAccess data, ICallMonitor callMonitor) { ... }
Тогда ваш тест может добавить в конструктор экземпляр заглушки / макета этого интерфейса.
РЕДАКТИРОВАТЬ: Если вы действительно не можете внедрить экземпляр в конструктор, у вас есть несколько вариантов:
Создайте фабрику, которую вы можете заглушить:
public class CallMonitorFactory
{
public virtual CallMonitor CreateMonitor(args...) { }
}
public DeviceMediator(IDeviceControlForm form, IDataAccess data, CallMonitorFactory factory)
{
this.form = form;
this.data = data;
CallMonitor = factory.CreateMonitor(OnIncomingCall);
}
Добавить защищенный фабричный метод в DeviceMediator, который возвращает CallMonitor. Затем вам нужно будет вручную создать подкласс DeviceMediator в своем тесте, чтобы вы могли вернуть фиктивный объект CallMonitor.
Переместите аргумент конструктора для CallMonitor в метод / свойство, которое вызывается в конструкторе DeviceMediator.
Похоже, вы пытаетесь прослушать какое-то событие на CallMonitor, поэтому вы можете (и должны, если это так) добавить событие, на которое подписывается DeviceMediator. В этом случае вы можете использовать RhinoMock, чтобы смоделировать вызов, вызывающий событие, следующим образом:
[Test]
public void IncomingCallTest()
{
IEventRaiser callEvent;
CallMonitor monitor = mocks.Stub(args..);
using(mocks.Record())
{
callEvent = monitor.Stub(m => m.IncomingCall += null).IgnoreArguments().GetEventRaiser();
//rest of expectations...
}
using(mocks.Playback())
{
DeviceMediator mediator = new DeviceMediator(form, data, monitor);
callEvent.Raise(sender, args);
}
}
Однако, как отмечено выше, вы не можете смоделировать вызовы конструктора с помощью RhinoMock, поскольку это потребует некоторых изменений в сгенерированном IL (при условии, что это даже возможно).