【发布时间】:2014-09-05 05:04:22
【问题描述】:
如何使用 moq 从模拟存储库中检索模拟对象?
我有一个应用程序 (mvc2),从一开始就没有真正设计来支持测试单元,但我正在尝试对其进行调整。 我有一个创建所需类型的服务定位器。
基本上我想要使用模拟框架做的是用模拟对象替换表示方法中服务的变量,然后我想检索模拟对象并设置它们。
所以:
private ApprovalLevel GetApprovalLevel(Fusion Fusion)
{
var ScopeofService=ServiceLocator.GetInstance<IScopeofService>();
var programs=ScopeofService.GetPrograms();
...
}
在我的测试单元中,我将 ServiceLocator 设置为使用模拟内核来模拟我的 IScopeofService,这可以正常工作。模拟内核使用作为参数发送的模拟存储库 MockRepository Moq,它将为所需接口绑定并创建所需的模拟。
现在我想在我的测试中检索该模拟,以设置要为 GetPrograms() 返回的假值,但我的 MockRepository 没有获取模拟只是创建新模拟的方法。
他仍然以某种方式保留了对模拟的所有引用,因为它具有 VerifyAll 方法。
更新
public MockNinjectControllerFactory(Moq.MockRepository mockRepository)
{
Kernel = new StandardKernel(new MockNinjectServices(mockRepository));
}
public class MockNinjectServices : NinjectModule
{
private readonly MockRepository _mockRepository;
public MockNinjectServices(MockRepository _mockRepository)
{
this._mockRepository = _mockRepository;
}
// TODO MARIAN: Resolver should return actualy mock objects also to be able to set them.
public void BindToConstant<T>() where T : class
{
Bind<T>().ToConstant(_mockRepository.Create<T>().Object).InSingletonScope();
}
public void BindMock<T>() where T : class
{
Bind<Mock<T>>().To(typeof(Mock<T>)).InSingletonScope();
}
public override void Load()
{
BindToConstant<IPaymentInvoiceRep>();
BindToConstant<IPaymentInvoiceBL>();
}
}
还有测试本身:
[TestFixture]
public class DemoControllerFixture
{
readonly MockRepository _mockRepository = new MockRepository(MockBehavior.Default);
[Test]
public void Should_MyMethod()
{
EvedServiceLocator.Default = new MockNinjectControllerFactory(_mockRepository);
var sut=new DemoController();
// now if my sut has something that will resolve as mock created by my mockRepository I would like to retrieve that mock and set up something on it.
}
}
【问题讨论】:
-
我很难理解您遇到了什么问题。在您尝试设置服务定位器的测试中发布代码,并尝试稍微澄清您的问题。
-
您好,感谢您的回答,我已经发布了有关我的代码的更新。
-
在我看来更像是依赖注入问题,而不是模拟框架问题。在 DI 中,您首先需要在容器中“注册”一个依赖项,然后让框架在运行时“解决”它。在您提供的源代码中,我看不到 IScopeofService 正在注册和解析。
-
依赖解析器使用mockRepository创建mock没有问题,mock就创建好了。问题是之后检索模拟。 BindMock 方法将服务绑定到模拟对象。所以我没有 DI 问题。关键是 Moq.dll V4.2.1402.2112 中的 MockRepository。没有任何方法来获取模拟引用,而是有类似 verifyAll() 的方法。
-
也许我使用这样的模拟框架是错误的,但我认为它会起作用。我有一些 NinjectSettings 可以为我提供具体类型,另一方面,一些 MockingNinjectSettings 和一个 mockingkernel 将模拟所有私有变量、成员,它们通常会通过服务定位器解析。我要做的就是不公开所有通过服务定位器解析的服务,作为属性或注入构造函数。