【问题标题】:moqing static method call to c# library classc#库类的moqing静态方法调用
【发布时间】:2010-03-09 06:21:54
【问题描述】:

这似乎是一个很简单的问题,但我似乎找不到关键字来影响我的搜索。

我正在尝试通过模拟此方法调用中的所有对象来进行单元测试。我可以对我自己的所有作品都这样做,除了这个:

public void MyFunc(MyVarClass myVar)
{
    Image picture;
    ...

    picture = Image.FromStream(new MemoryStream(myVar.ImageStream));

    ...
}

FromStream 是来自 Image 类(c# 的一部分)的静态调用。那么我该如何重构我的代码来模拟它,因为我真的不想为单元测试提供图像流。

【问题讨论】:

    标签: unit-testing refactoring moq


    【解决方案1】:

    您可以创建一个 IImageLoader 接口。 “正常”实现只调用 Image.FromStream,而您的单元测试版本可以做任何您需要做的事情。

    【讨论】:

    • 这意味着我必须为每个对不同类进行的静态方法调用创建一个接口。我希望有一种更优雅的方式来做到这一点......
    • 不,没有运行时帮助的静态编译语言没有优雅的方法来解决这个问题。有一种方法可以通过利用分析 CLR API(非常复杂)来做到这一点。这就是 TypeMock 的工作原理
    • 除了 CVertex 使用 TypeMock 的解决方案之外,真的没有办法。静态方法和单元测试并不能很好地结合在一起。
    【解决方案2】:

    Moq 和大多数其他模拟框架不支持模拟静态方法。但是,TypeMock 确实支持模拟静态方法,如果您愿意购买它,您可能会感兴趣。否则,您将不得不重构以便可以模拟接口...

    【讨论】:

    • MSR 的鼹鼠也在这个空间里玩耍
    【解决方案3】:

    您可以将静态函数包装到 Func 类型属性中,该属性可以通过单元测试使用模拟或存根进行设置。

    public class MyClass
    {
        ..
    
        public Func<Image, MemoryStream> ImageFromStream = 
                                         (stream) => Image.FromStream(stream);
    
    
        public void MyFunc(MyVarClass myVar)
        {
            ...
    
            picture = ImageFromStream(new MemoryStream(myVar.ImageStream));
    
            ...
        }
    
    
        ..
    }
    

    【讨论】:

    • 我认为就像封装成一个接口的想法一样,如果我要在我的代码中拥有多个静态调用实例,这个解决方案就不能很好地扩展。我必须为每个静态调用创建一个函数。有没有办法从库类中模拟出静态方法?
    • 您只需要为不同的静态方法创建一个属性,因为您可以重用它们。我相信 TypeMock 可以模拟静态方法,使用一些 IL 编织,但它不是免费的。恐怕在 C# 中将可测试的代码解耦需要做很多工作。
    • 经过一番思考,提供的接口和函数解决方案都很混乱,但是这个函数解决方案比创建一个新的接口和类来模拟一个静态函数所用的行更少。所以我要和这个一起去。感谢所有的答案。
    【解决方案4】:

    这可以通过 Moles(一个 Visual Studio 2010 电动工具)来实现。 Moles 代码如下所示:

    // replace Image.FromStream(MemoryStream) with a delegate
    MImage.FromStreamMemoryStream = stream => null; 
    

    【讨论】:

      猜你喜欢
      • 2011-01-17
      • 2010-10-10
      • 2014-10-04
      • 2018-03-14
      • 1970-01-01
      • 2012-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多