首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Castle.Windsor工厂方法中使用Moq会引发

在Castle.Windsor工厂方法中使用Moq会引发
EN

Stack Overflow用户
提问于 2018-01-22 16:20:02
回答 3查看 604关注 0票数 1

我在Castle.Windsor (v4.1.0)的工厂方法中使用Moq (v4.8.1)时遇到了一个问题。我想知道是否有其他人遇到过这个问题,以及他们做了什么来解决这个问题。

我有一个简单的接口,定义如下:

代码语言:javascript
复制
interface IFoo
{
    Task DoFooAsync(Bar bar);
}

在我的主项目中,我在WindsorContainer中注册了以下内容:

代码语言:javascript
复制
container
    .Register(Component.For<IFoo, Foo>()
    .LifestyleTransient());

这可以在运行时很好地解决。

在我的测试项目中,我执行以下操作:

代码语言:javascript
复制
container.Register(Component.For<IFoo>().UsingFactorymethod(() => {
    var mock = new Mock<IFoo>();
    mock
        .Setup(x => x.DoFooAsync(It.IsAny<Bar>()))
        .Returns(() => Task.FromResult(true));
    return mock.Object;
})
.IsDefault());

在测试来自Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.ApplyCommissionConcerns(Object实例的消息时失败):

“无法将委托问题应用于组件后期绑定MyAssembly.IFoo,因为它似乎是无目标代理。当前不支持这些代理。”

注意:'IsDefault()‘只是为了让Castle.Windsor覆盖来自主项目的注册,它与这个问题无关(我尝试在没有它的情况下运行,但问题仍然存在)。

如果我改为执行以下操作:

代码语言:javascript
复制
// exact same code as above, just placed outside the factory method
var mock = new Mock<IFoo>();
mock
    .Setup(x => x.DoFooAsync(It.IsAny<Bar>()))
    .Returns(() => Task.FromResult(true));

// different registration
container
    .Register(Component.For<IFoo>()
    .Instance(mock.Object).IsDefault());

然后一切都能正常工作。但是现在,每次解析IFoo时都会重用我的IFoo实例-这与我的主项目中的行为不同,因此不需要。

我研究了Castle.Windsor代码以了解发生了什么,但没有取得真正的成功。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-01-22 21:54:07

Moq在内部使用Castle的动态代理,而mocked类实际上是由Castle生成的代理,这正是由于某些内部原因Castle的开发人员不想支持的。你可以在这里了解更多:

https://github.com/castleproject/Windsor/issues/224

https://github.com/castleproject/castle-youtrack-export/blob/master/IOC/IOC-332.xml

因此,正如Nkosi已经评论的那样,您应该更多地考虑您真正需要实现的目标,并重新考虑您的设计。

票数 1
EN

Stack Overflow用户

发布于 2018-01-22 18:13:38

每次解析IFoo时都会重用我的IFoo实例-这与我的主项目中的行为不同,因此不需要。

用lambda创建一个属性怎么样?类似于:

代码语言:javascript
复制
private IFoo TheMock => CreateMock();
private IFoo CreateMock()
{
   var mock = new Mock<IFoo>();
   mock
    .Setup(x => x.DoFooAsync(It.IsAny<Bar>()))
    .Returns(() => Task.FromResult(true));
   return mock.Object;
}

然后注册它

代码语言:javascript
复制
container
.Register(Component.For<IFoo>()
.Instance(TheMock).IsDefault());

免责声明:我没有测试过,因为我没有使用Castle.Windsor。

票数 0
EN

Stack Overflow用户

发布于 2018-12-07 08:57:54

这对我很有效。UsingFactoryMethod()失败了。它使用injection来代替伪注入。

代码语言:javascript
复制
var blobservice = Substitute.For<IBlobFileService>();           
RegisterFakeServiceInstance(blobservice);
private void RegisterFakeServiceInstance<TService>(TService fakeService) where TService : class
{
    IocManager.IocContainer.Register(
    Component.For<TService>()
           .Instance(fakeService)
           .LifestyleSingleton()
    );
 }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48377240

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档