Mock.Of<Object> VS Mock<Object>()

Posted

技术标签:

【中文标题】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 中设置属性。

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

【问题讨论】:

这是答案 - cmatskas.com/improve-your-unit-tests-with-mock-of 【参考方案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.Of : Old 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"),
);

【讨论】:

以上是关于Mock.Of<Object> VS Mock<Object>()的主要内容,如果未能解决你的问题,请参考以下文章

反应器:Flux<object> .subscribe() 与 .toStream()

Parallel vs Await vs Result - 哪个更适合延迟执行

NX-二次开发删除对象UF_OBJ_delete_object

SQL Server Object Explorer in VS

NX二次开发-UFUN遍历获得可用对象UF_MODL_ask_object

NX二次开发-UFUN遍历获得可用对象UF_MODL_ask_object