模拟 Unity 容器时出现异常
我正在尝试模拟一个统一容器 - 我使用 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 Test 很重要...
谢谢,
这是整个测试装置 - 你可以看到我已将其更改为使用真正的统一容器,但理想情况下我不想创建真正的统一容器 - 这不是我正在测试的。不过,您可以看到我注释掉的代码...
[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);
}
谢谢!
I am trying to mock a unity container - I using Moq and Getting this errror
System.ArgumentException: Invalid setup on a non-overridable member:
c => c.Resolve<ILogisticsAdapter>(new [] {})
Here is the code from the setup portion of my test.
var mockContainer = new Mock<IUnityContainer>();
mockContainer.Setup(c => c.Resolve<ILogisticsAdapter>()).Returns(logicsticsAdapter);
IUnityContainer container = mockContainer.Object;
What am I missing? I am no master at mocks in general or unit testing but from what I can tell this should work...
Just in case it is important I am using VS2010 and MS Test...
Thanks
Here is the whole test fixture -you can see I have changed it to use a real unity container however ideally I don't want to create a real unity container - it isn't what I am testing. You can however see the code I commented out...
[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);
}
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我强烈同意上述评论者的观点 - 您不应该(在大多数情况下)在引导程序之外的任何地方引用容器。在您的情况下,您似乎正在实现视图模型定位器类型的类,因此可能没问题。不过,请仔细考虑一下这样做是否正确。通常使用显式工厂或让容器注入 Func 可以让您达到相同的位置,而无需显式地将您耦合到容器。
话虽如此,如果您使用的是 Unity 2.0,请仔细查看 IUnityContainer 界面。您会看到您尝试模拟的方法实际上并不在界面上。这是一种扩展方法。 IUnityContainer 实际上只有一个“本机”解析方法:
因此您需要专门模拟该方法。扩展方法只是做一些参数调整,然后调用直接在界面上的 Resolve。
您可能仍然会遇到问题 - 实际上 .NET 框架中存在一个错误,当对具有返回接口的方法的接口实现进行代码生成时会导致问题,RegisterType、RegisterInstance 以及 IUnityContainer 上的所有其他方法都会这样做。这是我目前所知道的所有模拟框架的一个问题。如果您确实遇到了这个问题,唯一的选择就是手动模拟 - 自己编写一个实现 IUnityContainer 的类,而不是使用模拟框架来实现它。
I strongly agree with the above commenters - you shouldn't (in most cases) be referencing the container anywhere other than the bootstrapper. In your case, it looks like you're implementing a view model locator type of class, so it might be ok. However, please think carefully about whether this is the right thing to do. Usually using explicit factories or getting Func injected by the container will get you the same place without coupling you explicitly to the container.
Having said that, if you're using Unity 2.0, take a good look at the IUnityContainer interface. You'll see the method you're trying to mock out isn't actually on the interface. It's an extension method. IUnityContainer actually only has one "native" resolve method:
So you'll need to mock that method specifically. The extension methods just do some parameter juggling and turn around and call the Resolve that's directly on the interface.
You might still run into issues - there's actually a bug in the .NET framework that causes problems when codegenning implementations of interfaces that have methods that return the interface as well, which the RegisterType, RegisterInstance, and, well every other method on IUnityContainer does. This is a problem with just about all the mocking frameworks I know of right now. If you do hit this, the only option would be a manual mock - write a class that implements IUnityContainer yourself rather than using the mock framework to do it.