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