【问题标题】:Spy an object with Moq (C#)使用 Moq (C#) 监视对象
【发布时间】:2019-08-28 12:37:54
【问题描述】:

我正在构建一个 .NET Core 应用程序,我想使用 Moq 监视一个实例化对象,但我还没有找到方法。

基本上,我需要的是被描述为here 的间谍活动。

我发现我可以使用以下方式调用类Foo的基类方法:

 var mock = new Mock<Foo>();
 mock.CallBase = true;

我的问题是 Moq 将创建一个 Foo 的新实例,而我需要的是使用已经实例化的对象并在调用对象的真实函数时仅模拟真实对象的一种方法。

这是我要监视的对象的结构。

    public class Foo:Boo
    {
       Foo(Propeties props):base(props){}

       public Baz MockMe(){...}

       public Daz DoNotMockMe(){ 
           return DoSomethingWith(Properties);
        }
    }

【问题讨论】:

    标签: c# moq spy


    【解决方案1】:

    起订量不支持现有对象。但是,它确实接受参数来调用构造函数。当我们使用像装饰器模式这样的解决方法时,这可能是解决方案。

    请注意,使用(现有)实例时需要注意:使用您的模拟实例 (carMock.Object) 的类使用您配置的设置。但是,被测类本身 (actualCar) 并不知道它正在被修饰,因此 not 如下例所示。

    public class Car : ICar
    {
        public virtual string Manufacturer { get; set; }
        public virtual string Model { get; set;}
        public virtual string Name => $"{Manufacturer} {Model}";
    }
    
    public class CarTestHelper : ICar
    {
        private readonly ICar _innerCar;
    
        public CarTestHelper(ICar car)
        {
            _innerCar = car;
        }
    
        // These properties use the existing instance passed in the constructor
        public string Manufacturer { get => _innerCar.Manufacturer; set => _innerCar.Manufacturer = value; }
        public virtual string Model { get => _innerCar.Model; set => _innerCar.Model = value; } // Virtual property can be mocked using Moq
        public string Name => _innerCar.Name; // Does NOT use mocked 'Model'.
    }    
    
    [TestFixture]
    public class CarTests
    {
        [Test]
        public void NameIsManufacturerWithModel()
        {
            var actualCar = new Car
            {
                Manufacturer = "Nissan",
                Model = "100NX"
            };
    
            var carMock = new Mock<CarTestHelper>(actualCar)  // Pass the decorated car as constructor parameter
            {
                CallBase = true
            };
    
            carMock.SetupGet(c => c.Model).Returns("200SX");
    
            Assert.AreEqual("Nissan 200SX", carMock.Object.Name);  // Will fail as the car will not used the mocked value.
        }
    }
    

    Visual Studio 有一个很好的快速修复,可以在您从 ICar 继承并将其作为构造函数参数时自动实现装饰器模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-16
      • 1970-01-01
      • 2012-11-09
      • 2013-06-20
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多