在c#中模拟类中的实例

本文关键字:实例 模拟类 | 更新日期: 2023-09-27 17:51:18

我试图模拟类中的实例。这是类(简化):

public void CreatePhotos(string elementType) 
{ 
    var foo = new PicturesCreation(); 
    //some code here...
    if (elementType == "IO") 
    { 
        foo.CreateIcons(client, new PicturesOfFrogsCreation(), periodFrom, periodTo)
    } 
}

所以我试着模拟这个'new PicturesOfFrogsCreation()'进行单元测试,看看CreateIcons是否用这个参数调用。我试图使用Rhino Mocks/AssertWasCalled方法在我的测试中实现这一点,但它看起来不工作,因为我只知道如何模拟接口。你知道是否可以嘲笑这个吗?

更新:类的代码:

internal sealed class PicturesCreation 
    { 
      public void CreateIcons(IPictures foo, int periodFrom, int periodTo) 
         { 
            foo.CreateIcons(periodFrom, periodTo); 
         } 
    }

和picturesoffrogcreation的代码:

internal sealed class PicturesOfFrogsCreation : IPictures
{ 
    public void CreateIcons(int periodFrom, int periodTo) 
      { 
         //Code that implements the method
      } 
}

我写了这个测试,但我不确定它是否写得好:

public void Create_commitment_transaction_should_be_called_for_internal_order() 
    { 
       IPicture fooStub = RhinoStubWrapper<IPicture>.CreateStubObject(); 
       rebuildCommitmentsStub.StubMethod(x => x.CreateIcons(Arg<int>.Is.Anything, Arg<int>.Is.Anything));
       PicturesProcess.CreatePhotos("IO"); 
       rebuildCommitmentsStub.AssertWasCalled(x => x.CreateIcons(Arg<int>.Is.Anything,Arg<int>.Is.Anything));
    }

提前感谢!

a .

在c#中模拟类中的实例

你的代码似乎不是为了这个而设计的。因为您是在方法中实例化实例,然后调用该方法,所以很难模拟它。

如果您将实例传递给此方法,或者传递给要在字段中捕获的类的构造函数,则可以用mock替换它-大多数mock框架(包括Rhino)都可以这样做,只要您正在检查的方法是虚拟的。


编辑:我从你的编辑中看到有问题的类是密封的。这使得他们本质上是不可嘲笑的。模拟类的工作原理是创建一个代理类,该代理类继承于被模拟的类——如果它是密封的,则不能这样做。

您需要注入您希望模拟的依赖项。局部变量对方法来说是私有的,不能断言。示例-

public class Photo{
  private IPicturesCreation foo;
  public test(IPicturesCreation picturesCreation)
  {
    foo = picturesCreation;
  }
  public void CreatePhotos(string elementType) 
    { 
    //some code here...
    if (elementType == "IO") 
       { 
           foo.CreateIcons(client, new PicturesOfFrogsCreation(), periodFrom, periodTo)
       } 
    }
}

然后像这样测试

public class PhotoTest{
    public testFunctionCall(){
    var mockPicturesCreation = new Mock<IPicturesCreation>();
    new Photo(mockPicturesCreation.Object).CreatePhotos("blah");
    mockPicturesCreation.Verify(x => x.CreateIcons(.....), Times.Once);
    }
}

正如其他人已经提到的,这段代码不太适合模拟。然而,如果你不能修改代码,仍然有一些选择。

我听说TypeMock可以模拟密封类,但我从未使用过它。顺便说一下,这是商业软件…还有微软Fakes框架(附带VS Premium)。我试用了一下,发现你几乎可以测试任何东西。绝对值得一试!