代码之家  ›  专栏  ›  技术社区  ›  Russell Giddings

在Mock中检查更新的实例

  •  3
  • Russell Giddings  · 技术社区  · 14 年前

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

    我想知道的是,在最小起订量中是否有一个很好的方法来检查以下各项:-

    1. 保存回服务的实例是原始实例的修改版本
    2. 实例已按需要更新

    It.Is<MyThing>(x => x.Name == newName)

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

    类别代码:

    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();
    }
    
    3 回复  |  直到 14 年前
        1
  •  1
  •   Jeff Sternal    14 年前

    如果我理解正确,您需要验证传递给 ts.Save

    如果这是真的,除了验证 Name 价值满足您的期望:

    thingService
         .Setup(ts => ts.Save(It.Is<MyThing>(thing => thing == thingFromService
                                                   && thing.Name = myThing.Name))
         .Verifiable();
    
        2
  •  1
  •   Mark Seemann    14 年前

    [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();
    }
    

    主要的区别是我还添加了一个 Verifiable() It.Is Verify

    Assertion Roulette ,最好将其分为两个测试。

        3
  •  0
  •   Greg Roberts    14 年前

    相同的对象引用或对象类型 ? It.Is只是确保参数是 神话 ,并不是说它是对上一个对象的实际引用。

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

    MyThing result = null;
    
    thingService
        .Setup(ts => ts.Save(It.Is<MyThing>(x => x.Name == myThing.Name)))
        .Callback((MyThing saved) => result = saved)
        .Verifiable();