Rhino 模拟和在 using 语句中创建的对象

发布于 2024-10-06 08:38:10 字数 767 浏览 4 评论 0原文

大多数时候,当我们使用Rhino模拟时,它工作得很好,但是我们在模拟使用using语句创建的对象时遇到问题。

我们有一个 WCF 代理,其实现如下:

public class MyProxy : System.ServiceModel<IMyProxy>, IMyProxy
{
    public Response DoWork(Request request)
    {
         return base.Channel.DoWork(request);
    }
}

通常在我们的业务层中,我们会有一个属性:

 IProxy MyProxy;

我们可以将其设置为模拟接口。

但是当我们使用 using 语句时,我们的业务层看起来像这样:

using (MyProxy proxy = new MyProxy())
{
}

它实例化了类的具体实现。

我们如何让业务层使用通过Rhino模拟创建的模拟?

编辑

事实证明,您不应该将using语句与wcf代理一起使用http://msdn.microsoft.com/en-us/library/aa355056.aspx

Most of the time when we use Rhino mocks it works well, but we have problems mocking objects created using the using statements.

We have a WCF proxy that is implemented as follows:

public class MyProxy : System.ServiceModel<IMyProxy>, IMyProxy
{
    public Response DoWork(Request request)
    {
         return base.Channel.DoWork(request);
    }
}

Normally in our business layer we would have a property:

 IProxy MyProxy;

Which we could set as being the mocked interface.

But when we use a using statement, our business layer looks like this:

using (MyProxy proxy = new MyProxy())
{
}

Which instanciates the concrete implementation of the class.

How do we get the business layer to use the mock created with Rhino mocks?

Edit

It turned out that you should not use using statements with wcf proxies http://msdn.microsoft.com/en-us/library/aa355056.aspx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

相权↑美人 2024-10-13 08:38:10

Func 注入您的类中,并将其存储在字段中。

然后,您的代码将变为

public class MyClass
{
    private readonly Func<IProxy> createProxy;

    public MyClass(Func<IProxy> createProxy)
    {
        if (createProxy == null)
            throw new ArgumentNullException("createProxy");
        this.createProxy = createProxy;
    }

    public void DoSomething()
    {
        using (IProxy proxy = this.createProxy())
        {
            ...
        }
    }
}

您的单元测试,然后如下所示:

[Test]
void MyClass_does_something()
{
    var proxyStub = MockRepository.CreateStub<IProxy>();
    var myClass = new MyClass(delegate { return proxyStub; });

    myClass.DoSomething();

    // make assertions...
}

请注意,有更多关系 除了简单的“A需要B”和“A创造B”之外。

我假设 IProxy 派生自 IDisposable 。这有点简化:代理实例也可能具有由容器创建的其自身的一次性依赖项。您不能总是假设这些依赖项需要与请求的对象同时处理。这就是为什么最好使用 Owned,如我上面链接的博客文章中所示。

Inject Func<IProxy> into your class, and store it in a field.

Your code then becomes

public class MyClass
{
    private readonly Func<IProxy> createProxy;

    public MyClass(Func<IProxy> createProxy)
    {
        if (createProxy == null)
            throw new ArgumentNullException("createProxy");
        this.createProxy = createProxy;
    }

    public void DoSomething()
    {
        using (IProxy proxy = this.createProxy())
        {
            ...
        }
    }
}

Your unit test then looks like this:

[Test]
void MyClass_does_something()
{
    var proxyStub = MockRepository.CreateStub<IProxy>();
    var myClass = new MyClass(delegate { return proxyStub; });

    myClass.DoSomething();

    // make assertions...
}

Note that there more relationships other than simple "A needs B" and "A creates B".

I have assumed that IProxy derives from IDisposable here. This is a bit of a simplification: the proxy instance may also have disposable dependencies of its own created by the container. You can't always just assume that those dependencies need to be disposed at the same time as the requested object. That's why it is better to use Owned<T> as illustrated in the blog post I linked above.

酒儿 2024-10-13 08:38:10

我怀疑这里的问题是 using 语句 - 我希望它使用构造函数。

解决这个问题的一种方法是使用依赖注入为对象提供一个相关对象的提供者(也称为工厂)。在测试中,您可以给它一个返回您的模拟对象的提供者。

I doubt that it's the using statement that's the problem here - I expect it's the fact that it's using a constructor.

One way round this is to use dependency injection to give the object a provider (aka factory) for the object in question. In tests, you can then give it a provider which returns your mock object.

淡紫姑娘! 2024-10-13 08:38:10

我会更改代码以使用 IoC 系统,看起来更像:

using (IMyProxy proxy = IoC.Resolve<IMyProxy>())
{
}

使用 IMyProxy 继承 IDisposable
然后在测试环境中,将 IoC 设置为返回模拟而不是运行时类型。

I would change the code to use an IoC system, to look more like:

using (IMyProxy proxy = IoC.Resolve<IMyProxy>())
{
}

With IMyProxy inheriting IDisposable.
Then in the test environment, set up the IoC to return the mock instead of the runtime type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文