C# 在C中模拟类内的实例#

C# 在C中模拟类内的实例#,c#,rhino-mocks,C#,Rhino Mocks,我试图在类中模拟一个实例。这是课程(简化): 因此,我试图模拟这个“new PicturesOfFrogsCreation()”进行单元测试,以查看是否使用此参数调用CreateIcons。我试图在测试中使用Rhino Mocks/AssertWasCall方法来实现这一点,但它似乎不起作用,因为我只知道如何模拟接口。你知道有没有可能嘲笑这个 更新:PicturesCreation类的代码: internal sealed class PicturesCreation {

我试图在类中模拟一个实例。这是课程(简化):

因此,我试图模拟这个“new PicturesOfFrogsCreation()”进行单元测试,以查看是否使用此参数调用CreateIcons。我试图在测试中使用Rhino Mocks/AssertWasCall方法来实现这一点,但它似乎不起作用,因为我只知道如何模拟接口。你知道有没有可能嘲笑这个

更新:PicturesCreation类的代码:

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

         { 
            foo.CreateIcons(periodFrom, periodTo); 
         } 
    }
以及PicturesOfFrogsCreation的代码:

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));

    }
public void Create\u commission\u transaction\u应该被称为\u for\u internal\u order()
{ 
ipacture fooStub=RhinoStubWrapper.CreateStubObject();
重建CommissionsStub.StubMethod(x=>x.CreateIcons(Arg.Is.Anything,Arg.Is.Anything));
PicturesProcess.CreatePhotos(“IO”);
RebuildCommissionsStub.AssertWasCalled(x=>x.CreateIcons(Arg.Is.Anything,Arg.Is.Anything));
}
提前谢谢


答:

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

如果您将实例传入,或者传入该方法,或者传入要在字段中捕获的类的构造函数,那么它可以被替换为一个mock-大多数mock框架(包括Rhino)都可以这样做,只要您检查的方法是虚拟的



编辑:我从你的编辑中看到有问题的类是密封的。这使得它们基本上不可修改。模拟类的工作原理是创建一个从被模拟的类继承的代理类-如果它是密封的,这是无法完成的。

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

如果您将实例传入,或者传入该方法,或者传入要在字段中捕获的类的构造函数,那么它可以被替换为一个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);
    }
}
公共类光照测试{
公共testFunctionCall(){
var mockPicturesCreation=new Mock();
新照片(mockPicturesCreation.Object);
mockPicturesCreation.Verify(x=>x.CreateIcons(…),Times.Once);
}
}

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

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);
    }
}
公共类光照测试{
公共testFunctionCall(){
var mockPicturesCreation=new Mock();
新照片(mockPicturesCreation.Object);
mockPicturesCreation.Verify(x=>x.CreateIcons(…),Times.Once);
}
}

正如其他人已经提到的,此代码不太适合模拟。 但是,如果不能修改代码,仍然有一些选项

我听说它可以模拟密封类,但我从未使用过。这是商业软件顺便说一句。。。
还有(与VS Premium一起提供的)。我玩了一点,看起来你几乎可以测试它。绝对值得一看

正如其他人已经提到的,此代码不太适合模拟。 但是,如果不能修改代码,仍然有一些选项

我听说它可以模拟密封类,但我从未使用过。这是商业软件顺便说一句。。。
还有(与VS Premium一起提供的)。我玩了一点,看起来你几乎可以测试它。绝对值得一看

提取接口并使用它而不是具体类型有什么问题?试着从排列->动作->断言的角度思考。嘲弄是你安排的一部分。通常,您将“模拟”创建您验证的对象的对象。例如,您可能会模拟存储库并描述返回“thing”的行为(即,模拟PicturesRepository并在要求pictureId==42时告诉它返回某个图片)。@sll:问题是“//some code here”有很多事例,我不应该碰它。如果它是重要的,我可以这样做,但这是一个小错误。提取接口并使用它而不是具体类型有什么问题?试着从排列->动作->断言的角度思考。嘲弄是你安排的一部分。通常,您将“模拟”创建您验证的对象的对象。例如,您可能会模拟存储库并描述返回“thing”的行为(即,模拟PicturesRepository并在要求pictureId==42时告诉它返回某个图片)。@sll:问题是“//some code here”有很多事例,我不应该碰它。如果是重要的事情,我可以做,但这是一个小错误。是的,我同意你的观点,它看起来很难测试,但我想我无法触摸它:(.不管怎样,当你谈到在方法中传递实例时,你是指PicturesCreation类?谢谢你的意见!不管是什么样的实例,你都在努力模仿它。我想你说过这实际上是PicturesOfFrogsCreation类。但是请注意我的编辑。是的,我同意你的观点,它看起来很难测试,但我想我不能触摸它:(.不管怎样,当你谈到在方法中传递实例时,你是指PicturesCreation类?谢谢你的意见!不管是什么样的实例,你都在努力模仿它。我不会