Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.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
C# 在Mock中检查更新的实例_C#_Unit Testing_Mocking_Moq - Fatal编程技术网

C# 在Mock中检查更新的实例

C# 在Mock中检查更新的实例,c#,unit-testing,mocking,moq,C#,Unit Testing,Mocking,Moq,我有一个方法,它调用一个服务来检索一个对象的实例,更新该实例,然后将该实例保存回该服务(代码如下) 我想知道的是,在Moq中是否有一种很好的方法来检查以下内容:- 要保存回服务的实例是原始实例的修改版本 实例已按需要更新 我知道我可以使用It.Is(x=>x.Name==newName)来检查这里的第2点。但这样做忽略了第1点 有没有一个干净的方法来实现这一点 类别代码: public class MyClass { private readonly IThingService thin

我有一个方法,它调用一个服务来检索一个对象的实例,更新该实例,然后将该实例保存回该服务(代码如下)

我想知道的是,在Moq中是否有一种很好的方法来检查以下内容:-

  • 要保存回服务的实例是原始实例的修改版本
  • 实例已按需要更新
  • 我知道我可以使用
    It.Is(x=>x.Name==newName)
    来检查这里的第2点。但这样做忽略了第1点

    有没有一个干净的方法来实现这一点

    类别代码:

    public class MyClass
    {
        private readonly IThingService thingService;
    
        public MyClass(IThingService thingService)
        {
            this.thingService = thingService;
        }
    
        public void SaveMyThing(MyThing myThing)
        {
            var existingThing = thingService.Get(myThing.Id);
            existingThing.Name = myThing.Name;
            thingService.Save(existingThing);
        }
    }
    
    public class MyThing
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
    public interface IThingService
    {
        MyThing Get(int id);
        void Save(MyThing myThing);
    }
    
    测试代码:

    [Test]
    public void Save_NewName_UpdatedThingIsSavedToService()
    {
        // Arrange
        var myThing = new MyThing { 
                                    Id = 42,
                                    Name = "Thing1"
                                };
        var thingFromService = new MyThing
                        {
                            Id = 42,
                            Name = "Thing2"
                        };
    
        var thingService = new Mock<IThingService>();
        thingService
            .Setup(ts => ts.Get(myThing.Id))
            .Returns(thingFromService);
        thingService
            .Setup(ts => ts.Save(**UPDATED-THING-FROM-SERVICE**))
            .Verifiable();
    
        var myClass = new MyClass(thingService.Object);
    
        // Act
        myClass.SaveMyThing(myThing);
    
        // Assert
        thingService.Verify();
    }
    
    [测试]
    public void Save\u NewName\u updatedThingsSavedToService()
    {
    //安排
    var myThing=新的myThing{
    Id=42,
    Name=“Thing1”
    };
    var thingFromService=新神话
    {
    Id=42,
    Name=“Thing2”
    };
    var thingService=new Mock();
    物流服务
    .Setup(ts=>ts.Get(myThing.Id))
    .返回(服务中的内容);
    物流服务
    .Setup(ts=>ts.Save(**UPDATED-THING-FROM-SERVICE**))
    .可验证();
    var myClass=newmyclass(thingService.Object);
    //表演
    myClass.SaveMyThing(myThing);
    //断言
    thingService.Verify();
    }
    
    您就快到了:

    [Test]
    public void Save_NewName_UpdatedThingIsSavedToService()
    {
        // Arrange
        var myThing = new MyThing { 
                                    Id = 42,
                                    Name = "Thing1"
                                };
        var thingFromService = new MyThing
                        {
                            Id = 42,
                            Name = "Thing2"
                        };
    
        var thingService = new Mock<IThingService>();
        thingService
            .Setup(ts => ts.Get(myThing.Id))
            .Returns(thingFromService)
            .Verifiable();
        thingService
            .Setup(ts => ts.Save(It.Is<MyThing>(x => x.Name == myThing.Name)))
            .Verifiable();
    
        var myClass = new MyClass(thingService.Object);
    
        // Act
        myClass.SaveMyThing(myThing);
    
        // Assert
        thingService.Verify();
    }
    
    [测试]
    public void Save\u NewName\u updatedThingsSavedToService()
    {
    //安排
    var myThing=新的myThing{
    Id=42,
    Name=“Thing1”
    };
    var thingFromService=新神话
    {
    Id=42,
    Name=“Thing2”
    };
    var thingService=new Mock();
    物流服务
    .Setup(ts=>ts.Get(myThing.Id))
    .Returns(thingFromService)
    .可验证();
    物流服务
    .Setup(ts=>ts.Save(It.Is(x=>x.Name==myThing.Name)))
    .可验证();
    var myClass=newmyclass(thingService.Object);
    //表演
    myClass.SaveMyThing(myThing);
    //断言
    thingService.Verify();
    }
    
    主要区别在于,我还在第一次设置中添加了对
    Verifiable()
    的调用,然后我添加了
    It.is
    检查您在回答中已经提到的内容。由于谓词的原因,只有当谓词的计算结果为true时,才会匹配Save方法,在这种情况下,
    Verify
    调用成功


    然而,这个测试实际上测试了两件事(Get和Save)。为了避免这种情况,最好将其分为两个测试。

    如果我理解正确,您需要验证传递给
    ts.Save
    的参数是否是从服务返回的实例

    如果这是真的,除了验证
    Name
    值是否满足您的期望之外,还要检查引用相等性:

    thingService
         .Setup(ts => ts.Save(It.Is<MyThing>(thing => thing == thingFromService
                                                   && thing.Name = myThing.Name))
         .Verifiable();
    
    thingService
    .Setup(ts=>ts.Save(It.Is(thing=>thing==thingFromService
    &&thing.Name=myThing.Name)
    .可验证();
    
    我同意Mark的回答,但你的第一句话让我有点困惑。你是想知道对象是相同的对象引用还是对象类型?It只是确保参数是虚构的类型,而不是对上一个对象的实际引用

    如果要截获传递给模拟服务的值,可以使用如下回调,然后对结果对象执行任何您想要的断言:

    MyThing result = null;
    
    thingService
        .Setup(ts => ts.Save(It.Is<MyThing>(x => x.Name == myThing.Name)))
        .Callback((MyThing saved) => result = saved)
        .Verifiable();
    
    MyThing result=null;
    物流服务
    .Setup(ts=>ts.Save(It.Is(x=>x.Name==myThing.Name)))
    .Callback((虚构保存)=>result=保存)
    .可验证();
    
    Yep,我理解这一点。对thingService的“Get”调用实际上是一个存根(而不是模拟),因此它不需要.Verify()。这段代码的问题是它没有区分传递更新版本的“thingFromService”实例传递给Save方法,并将传递给SaveMyThing方法的神话实例传递给SaveMyThing方法(我的问题中的第1点)。:-(我想检查它是否是与更新的propertyFantastic相同的对象引用!我希望“thing==thingFromService”返回false作为“thing.Name!=thingFromService.Name”.事实并非如此,因为thingFromService是在测试方法中更新的对象,因此也是一样的。这是漫长的一天;-)谢谢Jeff!