Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 对c#library类的moqing静态方法调用_Unit Testing_Refactoring_Moq - Fatal编程技术网

Unit testing 对c#library类的moqing静态方法调用

Unit testing 对c#library类的moqing静态方法调用,unit-testing,refactoring,moq,Unit Testing,Refactoring,Moq,这似乎是一个很容易的问题,但我似乎找不到影响我的搜索关键字 我试图通过模拟这个方法调用中的所有对象来进行单元测试。我可以对我自己的所有创造物这样做,除了这一个: public void MyFunc(MyVarClass myVar) { Image picture; ... picture = Image.FromStream(new MemoryStream(myVar.ImageStream)); ... } FromStream是来自Image类(c

这似乎是一个很容易的问题,但我似乎找不到影响我的搜索关键字

我试图通过模拟这个方法调用中的所有对象来进行单元测试。我可以对我自己的所有创造物这样做,除了这一个:

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

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

    ...
}

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

您可以创建一个IImageLoader接口。“普通”实现只调用Image.FromStream,而您的单元测试版本可以执行任何您需要的操作。

您可以将静态函数包装到Func type属性中,该属性可以由单元测试使用模拟或存根设置

public class MyClass
{
    ..

    public Func<Image, MemoryStream> ImageFromStream = 
                                     (stream) => Image.FromStream(stream);


    public void MyFunc(MyVarClass myVar)
    {
        ...

        picture = ImageFromStream(new MemoryStream(myVar.ImageStream));

        ...
    }


    ..
}
公共类MyClass
{
..
公共函数ImageFromStream=
(流)=>Image.FromStream(流);
公共无效MyFunc(MyVarClass myVar)
{
...
picture=ImageFromStream(新内存流(myVar.ImageStream));
...
}
..
}

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

这可以通过Visual Studio 2010 Power Tools来实现。代码如下所示:

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

这意味着我必须为我对不同类进行的每个静态方法调用创建一个接口。我希望有一种更优雅的方法来做到这一点…不,没有运行时的帮助,在静态编译语言中没有优雅的方法来解决这个问题。有一种方法可以通过利用剖析CLR API(非常复杂)来实现这一点。TypeMock就是这样工作的除了CVertex使用TypeMock的解决方案之外,真的没有办法。静态方法和单元测试并不能很好地结合在一起。我认为,就像包装成一个接口的想法一样,如果我的代码中有多个静态调用实例,这个解决方案的扩展性就不太好。我必须为每个静态调用创建一个函数。没有办法从库类模拟静态方法吗?您只需要为不同的静态方法创建一个属性,因为您可以重用它们。我相信TypeMock可以模拟静态方法,使用一些IL编织,但它不是免费的。在C#中,将代码解耦为可测试代码恐怕需要大量工作。经过一些思考,提供的接口和函数解决方案都很混乱,但这种函数解决方案比创建一个新接口和类来模拟一个静态函数所需的行数要少。所以我选择这个。谢谢你的回答。MSR的鼹鼠也在这个空间玩