我正在尝试模拟一个统一容器 - 我使用Moq并得到这个错误
System.ArgumentException: Invalid setup on a non-overridable member:
c => c.Resolve<ILogisticsAdapter>(new [] {})
以下是我测试的设置部分的代码。
var mockContainer = new Mock<IUnityContainer>();
mockContainer.Setup(c => c.Resolve<ILogisticsAdapter>()).Returns(logicsticsAdapter);
IUnityContainer container = mockContainer.Object;
我错过了什么?我不是一般的模拟或单元测试的主人,但从我能说的这应该工作......
以防万一我使用VS2010和MS测试......
由于
这是整个测试夹具 - 你可以看到我已经改变它使用真正的统一容器,但理想情况下我不想创建一个真正的统一容器 - 它不是我正在测试的。但是你可以看到我注释掉的代码......
[TestMethod]
public void WhenContructed_AdapterGetsSet()
{
//Prepare
ILogisticsAdapter logicsticsAdapter = new Mock<ILogisticsAdapter>().Object;
var mockEventAggregator = new Mock<IEventAggregator>();
mockEventAggregator.Setup(x => x.GetEvent<SetHelpMessageEvent>()).Returns(new SetHelpMessageEvent());
IEventAggregator eventAggregator = mockEventAggregator.Object;
IRegionManager regionManager = new Mock<IRegionManager>().Object;
//var mockContainer = new Mock<IUnityContainer>();
//mockContainer.Setup(c => c.Resolve<ILogisticsAdapter>(null)).Returns(logicsticsAdapter);
//IUnityContainer container = mockContainer.Object;
IUnityContainer container = new UnityContainer();
container.RegisterInstance<ILogisticsAdapter>(logicsticsAdapter);
container.RegisterInstance<IRegionManager>(regionManager);
container.RegisterInstance<IEventAggregator>(eventAggregator);
//Act
var warehouseOrdersViewModel = new WarehouseOrdersViewModel_Accessor(container);
Assert.IsNotNull(warehouseOrdersViewModel.logisticsAdapter);
}
谢谢!
答案 0 :(得分:7)
我非常同意上述评论者的意见 - 你不应该(在大多数情况下)在引导程序之外的任何地方引用容器。在您的情况下,看起来您正在实现类的视图模型定位器类型,所以它可能没问题。但是,请仔细考虑这是否是正确的做法。通常使用显式工厂或通过容器注入Func将使您获得相同的位置,而无需将您明确地耦合到容器。
话虽如此,如果您使用的是Unity 2.0,请仔细查看IUnityContainer界面。你会看到你试图模拟的方法实际上并不在界面上。这是一种扩展方法。 IUnityContainer实际上只有一个“本机”解析方法:
object Resolve(Type t, string name, params ResolverOverride[] resolverOverrides);
所以你需要专门模拟那个方法。扩展方法只是做一些参数杂乱并转向并直接在接口上调用Resolve。
你可能仍会遇到问题 - .NET框架中实际上存在一个错误,当代码生成具有返回接口的方法的接口的实现时会导致问题,其中包括RegisterType,RegisterInstance以及其他所有方法IUnityContainer。这与我现在所知的所有模拟框架有关。如果你做点击这个,唯一的选择是手动模拟 - 编写一个自己实现IUnityContainer的类,而不是使用模拟框架来实现它。