【问题标题】:C#: How to unit test a method that relies on another method within the same class?C#:如何对依赖于同一类中另一个方法的方法进行单元测试?
【发布时间】:2011-01-07 22:20:58
【问题描述】:

我有一个类似于以下的类:

public class MyProxy : ClientBase<IService>, IService
{
    public MyProxy(String endpointConfiguration) :
        base(endpointConfiguration) { }

    public int DoSomething(int x)
    {
        int result = DoSomethingToX(x); //This passes unit testing

        int result2 = ((IService)this).DoWork(x)

        //do I have to extract this part into a separate method just
        //to test it even though it's only a couple of lines?
        //Do something on result2
        int result3 = result2 ...

        return result3;
    }

    int IService.DoWork(int x)
    {
        return base.Channel.DoWork(x);
    }
}

问题在于,在测试时,我不知道如何模拟 result2 项目,而不会将使用 result2 获得 result3 的部分提取到单独的方法中。而且,因为它是单元测试,所以我不想深入测试 result2 返回的结果......我宁愿以某种方式模拟数据......就像,能够调用函数并替换它一个电话。

【问题讨论】:

    标签: c# unit-testing visual-studio-2010 mocking


    【解决方案1】:

    你喜欢模拟框架吗?

    Rhino Mocks 中的Partial Mock 功能似乎应该满足您的需求。

    【讨论】:

    • 我希望使用内置的 Microsoft 测试框架,但这似乎不是一个解决方案。我真的希望避免 Visual Studio Ultimate 所涉及的任何事情。
    • 我很好奇,您是否有理由避免超越工作室内置的东西?另外,您使用的是哪个版本的 Studio?
    • 微软官方解决方案之外的一切都需要永远得到批准。批准 jQuery 花了很长时间。一切都必须经过严格的安全测试、可用性测试、调试测试等。由于我需要继续我的项目,我希望找到一个微软(或基于代码)的解决方案。
    • 啊,非技术要求 :) 那么是的,因为你可以修改你的代码,你最好重构它以使测试更容易(例如,使 DoWork 的实现可插入)。
    【解决方案2】:

    你真的不能那样做。您有三个选择:

    • 子类 MyProxy 并覆盖 DoWork,这需要一些摆弄才能取悦编译器
    • 模拟 Channel 属性,这将要求它可以在基类中设置
    • 将 DoWork 移出另一个类,在构造函数中将 Channel 传递给它,然后在您的测试中模拟它

    【讨论】:

      【解决方案3】:

      执行以下操作:

      设置一个 IService 属性,例如:

      public IService MyService { get; set; }

      然后你可以这样做:int result2 = MyService.DoWork(x) 只要在构造函数中的某个地方或者你设置的任何东西MyService = this;

      如果您不想公开该属性,您可以将其设为私有或其他并使用访问器对其进行测试。

      【讨论】:

        【解决方案4】:

        您可以使用最新的 Microsoft Research 项目 Moles

        一旦你运行它,你就可以做以下事情

        MMyProxy.DoWork32 = () => put your mock result here.
        

        记住将moleBehavior 设置为未模拟方法的失败。

        【讨论】:

          【解决方案5】:

          我相信你在这里有一个设计问题,你的 IService.DoWork 应该很可能存在于另一个类中,它看起来只是对其他东西的薄包装。你有考虑重构它吗?

          如果它存在于另一个类中,则不需要任何特殊处理来模拟。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-08-24
            • 2016-12-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多