【问题标题】:How can I test blades in MVC Turbine with Rhino Mocks?如何使用 Rhino Mocks 在 MVC Turbine 中测试叶片?
【发布时间】:2011-01-20 14:04:11
【问题描述】:

我正在尝试在 MVC Turbine 派生站点中设置刀片单元测试。问题是我似乎无法模拟IServiceLocator 接口而不遇到以下异常:

System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
at System.Reflection.Emit.TypeBuilder._TermCreateClass(Int32 handle, Module module)
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateType()
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options)
at Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
at Rhino.Mocks.MockRepository.MockInterface(CreateMockState mockStateFactory, Type type, Type[] extras)
at Rhino.Mocks.MockRepository.CreateMockObject(Type type, CreateMockState factory, Type[] extras, Object[] argumentsForConstructor)
at Rhino.Mocks.MockRepository.Stub(Type type, Object[] argumentsForConstructor)
at Rhino.Mocks.MockRepository.<>c__DisplayClass1`1.<GenerateStub>b__0(MockRepository repo)
at Rhino.Mocks.MockRepository.CreateMockInReplay<T>(Func`2 createMock)
at Rhino.Mocks.MockRepository.GenerateStub<T>(Object[] argumentsForConstructor)
at XXX.BladeTest.SetUp()

我搜索的有关此错误的所有内容都导致我遇到 32 位与 64 位 DLL 编译问题,但 MVC Turbine 到处都使用服务定位器外观,我们没有遇到任何其他问题,只是使用 Rhino Mocks尝试嘲笑它。

在这个 NUnit 设置方法的第二行就炸了:

IRotorContext _context;
IServiceLocator _locator;

[SetUp]
public void SetUp()
{
    _context = MockRepository.GenerateStub<IRotorContext>();
    _locator = MockRepository.GenerateStub<IServiceLocator>();
    _context.Expect(x => x.ServiceLocator).Return(_locator);
}

顺便说一句;我试过实现一个假的实现IServiceLocator,认为我可以跟踪对类型注册方法的调用。这在我们的设置中不起作用,因为我们扩展了服务定位器的接口,如果类型不是基于 Unity 的,则不会调用注册逻辑。

【问题讨论】:

    标签: asp.net-mvc unit-testing nunit rhino-mocks turbine


    【解决方案1】:

    是的,我在测试 Turbine 的运行时时也遇到了 RhinoMocks 的相同问题。我不想这么说,但我通过在我需要的地方为 IServiceLocator 提供我自己的假货来解决这个问题,但正如你所解释的,你不能那样做。 :(

    我没有从你的问题中关注这篇文章,“如果类型不是基于 Unity 的”??

    【讨论】:

    • 哈维尔 - 感谢您的快速反馈;郑重声明,MVC Turbine 非常棒,我很欣赏它让 SoC 对我们网站上工作的每个人来说是多么容易。我们扩展了 IServiceLocator 接口以接受生命周期管理器对象。由于它们是 Unity 特定的,因此只有在底层对象是 UnityServiceLocator 时调用才会成功执行。我们在我们的站点和 MVC Turbine 之间添加了一个层,该层在其全局 HTTP 应用程序中定义和注册高级内容(例如,日志记录、cookie 管理),因此我们认为应该在刀片中定义较低级别的映射。有什么更好的方法吗?
    • 所以经过一些强烈的重构后,我做到了,以便我们可以在其静态构造函数中将类型注册添加到全局 Web 应用程序上的静态容器中。这样我就不必进行界面扩展黑客攻击了。
    • 很抱歉在这个问题上是 MIA,但我没有收到关于添加的通知。 :) 你做了多少重构?
    • 没问题,这里也一样。我们最终在框架层使用了一个静态统一容器,它执行高级注册。继承的 http 应用程序客户端也从静态构造函数执行其注册。我仍然必须制作一个假的 UnityContainer,以便我可以验证生命周期是否设置得当。最终效果很好,因为我们可以使类型注册的顺序清晰且集中。另外,我对编写不必要的 ServiceLocator 扩展感到不那么脏:)
    • 太棒了,很高兴听到!如果您不介意我问,您将 Turbine 用于什么类型的应用程序?
    【解决方案2】:

    此问题已在 Moq v4.0 测试版中得到修复。在为具有通用约束的接口创建动态代理时,Castle DynamicProxy 2.1 中存在问题。

    http://code.google.com/p/moq/issues/detail?id=177

    【讨论】:

    • +1 有趣...我没有意识到 Castle 是 Moq 和 RhinoMocks 的底层框架,直到我查看了它并重新阅读了我的堆栈跟踪
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多