【问题标题】:Mock.Of<Object> VS Mock<Object>()Mock.Of<Object> VS Mock<Object>()
【发布时间】:2016-08-30 18:30:36
【问题描述】:

我目前对如何模拟感到困惑。

我正在使用起订量。为了模拟对象,我通常这样写

 var mockIRepo = new Mock<IRepo>();

但是,我需要为我的设置创建模拟对象。

选项1 以这种方式模拟仅包含属性的对象会更好吗?

 var object = Mock.Of<Object>()

选项2 或者这样

 var object = new Mock<Object>()

我读到选项 2 有 setupproperties,这对我来说有点问题,因为我也可以在选项 1 中设置属性。

那有什么区别呢?还是有更好的方法?

【问题讨论】:

标签: c# unit-testing testing mocking moq


【解决方案1】:

根据上面的答案,我想当你最想模拟属性时,Mock.Of&lt;T&gt;() 更容易,而当你想模拟方法等时,Mock&lt;T&gt; 更容易。

  • 主要是模拟属性:
var foo = Mock.Of<Foo>();
foo.Property1 = 1;
foo.Property2 = 2;
foo.Property3 = 3;
  • 主要是模拟方法:
var barMock = new Mock<Bar>();
barMock.Setup(bar => bar.GetValue1()).Returns(1);
barMock.Setup(bar => bar.GetValue2Async()).ReturnsAsync(2);

【讨论】:

    【解决方案2】:

    两者都做同样的事情,但Mock.Of 是更“自然”的代码。

    使用Mock&lt;T&gt; 看起来更像这样(或者像您的代码一样使用设置/返回):

    var mockService = new Mock<ISomeService>();
    mockService.SetupProperty(s => s.IsActive);
    mockService.Object.IsActive = true;
    mockService.SetupProperty(s =>s.DelayTime);
    mockService.Object.DelayTime = 5000;
    

    使用Mock.Of&lt;T&gt; 可以直接获取实例,并且可以设置所需的值。 并且你可以使用Mock.Get()来配置任何方法:

    var mockService = Mock.Of<ISomeService>();
    mockService.IsActive = true;
    mockService.DelayTime = 5000;
    Mock.Get(mockService).Setup(s => s.ExecuteTask()).Returns(true);
    
    

    他们做同样的事情,但是对于具有很多属性和方法的更复杂的服务,我认为Mock.Of&lt;T&gt; 更具可读性

    【讨论】:

    • 您的Mock.Of&lt;&gt;() 示例代码仅在ISomeService 具有IsActiveDelayTime 的设置器时才有效。如果没有,请像这样声明:var mockService = Mock.Of&lt;ISomeService&gt;(mockService =&gt; mockService.IsActive == true &amp;&amp; mockService.DelayTime == 5000);
    【解决方案3】:

    这篇文章帮助我理解了 Mock.OfOld style imperative Mock<T> vs functional Mock.Of<T>

    正如帖子中所解释的那样,使用 Mock.Of 你是在说“给我一个表现得像这样的模拟”(或者如果你需要 Mocks.Of获得许多对象(IEnumerable))。它使 mock 的声明更加简洁。

    Mock 示例(返回一个 Mock)

    var el1 = new Mock<IElementInfo>();
    el1.Setup(x => x.Id).Returns(Guid.NewGuid());
    el1.Setup(x => x.Multiplicity).Returns(Multiplicity.Single);
    
    var c1 = new Mock<ICollectionInfo>();
    c1.Setup(x => x.Id).Returns(Guid.NewGuid());
    c1.Setup(x => x.Multiplicity).Returns(Multiplicity.Multiple);
    
    var p1 = new Mock<IPropertyInfo>();
    p1.Setup(x => x.Id).Returns(Guid.NewGuid());
    p1.Setup(x => x.Name).Returns("Foo" + Guid.NewGuid().ToString());
    p1.Setup(x => x.Type).Returns("System.String");
    
    var p2 = new Mock<IPropertyInfo>();
    p2.Setup(x => x.Id).Returns(Guid.NewGuid());
    p2.Setup(x => x.Name).Returns("Bar" + Guid.NewGuid().ToString());
    p2.Setup(x => x.Type).Returns("System.String");
    
    var elementInfoMock = new Mock<IElementInfo>();
    elementInfoMock.Setup(e => e.Id).Returns(Guid.NewGuid());
    elementInfoMock.Setup(e => e.Multiplicity).Returns(Multiplicity.Multiple);
    elementInfoMock.Setup(e => e.Elements)
        .Returns(new List<IAbstractElementInfo>
        {
            el1.Object,
            c1.Object,
        });
    elementInfoMock.Setup(x => x.Properties).Returns(
        new List<IPropertyInfo>
        {
            p1.Object,
            p2.Object,
        });
    
    this.elementInfo = elementInfoMock.Object;
    

    使用 Mock.Of 的相同示例(返回类的实例)

    this.elementInfo = Mock.Of<IElementInfo>(x =>
    x.Id == Guid.NewGuid() &&
    x.Multiplicity == Multiplicity.Multiple &&
    x.Elements == new List<IAbstractElementInfo>
    {
        Mock.Of<IElementInfo>(e => e.Id == Guid.NewGuid() && e.Multiplicity == Multiplicity.Single),
        Mock.Of<ICollectionInfo>(e => e.Id == Guid.NewGuid() && e.Multiplicity == Multiplicity.Single),
    } &&
    x.Properties == new List<IPropertyInfo>
    {
        Mock.Of<IPropertyInfo>(p => p.Id == Guid.NewGuid() && p.Name == "Foo" + Guid.NewGuid() && p.Type == "System.String"),
        Mock.Of<IPropertyInfo>(p => p.Id == Guid.NewGuid() && p.Name == "Foo" + Guid.NewGuid() && p.Type == "System.String"),
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-31
      • 2015-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      • 2011-12-30
      • 1970-01-01
      相关资源
      最近更新 更多