【问题标题】:Mocking concrete object properties with no setter在没有设置器的情况下模拟具体对象属性
【发布时间】:2014-03-05 13:53:48
【问题描述】:

我正在测试与第三方系统交互的服务。 API 公开的方法返回如下所示的对象:

public class Thing
{
    public string Name { get {...} }
    public string Description { get {...} }

    public Thing(string someUri)
    {
        /* Do some secret internal stuff and
           populate all my properties. */
    }
}

我需要模拟这些属性,以便根据返回的对象测试我的服务是否正确运行。

对象是一个具体类的实例,它没有实现我可以模拟的任何接口。这些属性的支持字段在Thing 的构造函数中设置,它接受一个URI,然后在一些紧密耦合的第三方系统中获取对象,并可能直接设置支持字段。

所有这一切意味着我无法模拟属性 - 我无法直接设置它们,我无法模拟接口,也无法模拟构造函数依赖项并以这种方式设置属性(无论如何都会降低我的测试的用处)。

有没有办法解决这个问题?

【问题讨论】:

    标签: c# unit-testing moq


    【解决方案1】:

    假设您在 Premium 或 Ultimate Edition 中使用 VS2012.2 或 VS2013,shims 应该可以满足您的需求。它们允许“填充”属性和构造函数,理想情况下仅适用于您发现自己所处的场景(不使用接口的第三方库)。

    在您的单元测试项目中为您的库添加 Fakes 程序集后,您将在单元测试中执行以下操作:

    using (ShimsContext.Create())
    {
        ShimThing.ConstructorString = (@this, value) => {
            var shim = new ShimThing(@this) {
                NameGet = () => "Your Desired Name",
                DescriptionGet = () => "Your Desired Description"
            };
        };
    
        //do whatever you need to do that creates a Thing object
    }
    

    我在没有实际尝试的情况下编写了这个示例,因此 ShimThing 构造函数的语法可能略有偏差。

    【讨论】:

      【解决方案2】:

      您可以使用 Shims(内置于 Visual Studio)来伪造 Thing

      http://msdn.microsoft.com/en-us/library/hh549175.aspx

      【讨论】:

      • 请注意,Fakes 和 Shims 需要 Visual Studio Premium 或 Ultimate。另一个更便宜的选择是TypeMock
      【解决方案3】:

      您可以只包装事物——这可能不是您要寻找的答案,因为它会涉及更改应用程序代码以支持您的单元测试,但它会导致代码库更松散,并且从长远来看,可能会让您的生活更轻松。

      创建一个ThingWrapper 类,该类将Thing 作为构造函数参数,其属性调用包装Thing 实例上的getter。然后就可以了

      • 将这些属性标记为virtual 并直接模拟包装器(更少代码)
      • 或让包装器针对该接口实现接口代码(可能更好)。

      希望这会有所帮助,对不起,如果我只是陈述显而易见的:/

      【讨论】:

      • 感谢您的回答,Joe - 不幸的是,我的问题可能并不明显,被测服务实际上已经是您描述的中间层包装器!
      • 很公平。如果是抽象层本身,那么它可能不值得进行单元测试; BDD 类型的集成测试可能更合适。我对假货有点怀疑,尤其是因为它们仅限于 VS Premium/Ultimate 版。这里有一些有趣的讨论:stackoverflow.com/a/11654698/332868
      猜你喜欢
      • 2014-01-07
      • 2011-05-01
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-16
      • 2011-11-30
      相关资源
      最近更新 更多