C# 模拟<;对象>;VS Mock<;对象>;()

C# 模拟<;对象>;VS Mock<;对象>;(),c#,unit-testing,testing,mocking,moq,C#,Unit Testing,Testing,Mocking,Moq,我现在对如何嘲笑感到困惑 我在用最小起订量。为了模仿对象,我通常这样写 var mockIRepo = new Mock<IRepo>(); var mockIRepo=new Mock(); 但是,我需要为我的设置创建模拟对象 选项1 这样模拟只包含属性的对象是否更好 var object = Mock.Of<Object>() var object=Mock.Of() 选项2 还是这样 var object = new Mock<Object>

我现在对如何嘲笑感到困惑

我在用最小起订量。为了模仿对象,我通常这样写

 var mockIRepo = new Mock<IRepo>();
var mockIRepo=new Mock();
但是,我需要为我的设置创建模拟对象

选项1 这样模拟只包含属性的对象是否更好

 var object = Mock.Of<Object>()
var object=Mock.Of()
选项2 还是这样

 var object = new Mock<Object>()
var object=new Mock()
我读到选项2有setupproperties,这对我来说有点可疑,因为我也可以在选项1中设置属性


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

这篇文章帮助我理解了Mock.Of:

正如在文章中解释的,对于Mock.Of,你会说“给我一个这样的Mock”(或者Mocks,如果你需要得到很多对象(IEnumerable))。它使mock的声明更加简洁

带有Mock的示例(返回一个Mock)

var el1=new Mock();
Setup(x=>x.Id).Returns(Guid.NewGuid());
设置(x=>x.Multiplicity).返回(Multiplicity.Single);
var c1=新的Mock();
c1.Setup(x=>x.Id).返回(Guid.NewGuid());
c1.设置(x=>x.Multiplicity).返回(Multiplicity.Multiple);
var p1=新的Mock();
p1.Setup(x=>x.Id).返回(Guid.NewGuid());
p1.Setup(x=>x.Name).返回(“Foo”+Guid.NewGuid().ToString());
p1.Setup(x=>x.Type).返回(“System.String”);
var p2=新的Mock();
p2.Setup(x=>x.Id).返回(Guid.NewGuid());
p2.Setup(x=>x.Name).返回(“Bar”+Guid.NewGuid().ToString());
p2.Setup(x=>x.Type).返回(“System.String”);
var elementInfoMock=new Mock();
elementInfoMock.Setup(e=>e.Id).Returns(Guid.NewGuid());
elementInfoMock.Setup(e=>e.Multiplicity).Returns(Multiplicity.Multiple);
elementInfoMock.Setup(e=>e.Elements)
.返回(新列表)
{
el1.反对,
c1.反对,
});
elementInfoMock.Setup(x=>x.Properties)。返回(
新名单
{
p1.反对,
p2.反对,
});
this.elementInfo=elementInfoMock.Object;
使用Mock.Of的相同示例(返回类的实例)

this.elementInfo=Mock.Of(x=>
x、 Id==Guid.NewGuid()&&
x、 多重性==多重性。多重性&&
x、 元素==新列表
{
Mock.Of(e=>e.Id==Guid.NewGuid()&&e.Multiplicity==Multiplicity.Single),
Mock.Of(e=>e.Id==Guid.NewGuid()&&e.Multiplicity==Multiplicity.Single),
} &&
x、 属性==新列表
{
Mock.Of(p=>p.Id==Guid.NewGuid()&&p.Name==“Foo”+Guid.NewGuid()&&p.Type==“System.String”),
Mock.Of(p=>p.Id==Guid.NewGuid()&&p.Name==“Foo”+Guid.NewGuid()&&p.Type==“System.String”),
});

两者的作用相同,但使用
Mock.Of
代码更“自然”

使用
Mock
看起来更像这样(或者像您的代码一样使用Setup/Return):

var mockService=new Mock();
mockService.SetupProperty(s=>s.IsActive);
mockService.Object.IsActive=true;
mockService.SetupProperty(s=>s.DelayTime);
mockService.Object.DelayTime=5000;
使用
Mock.Of
可以直接获取实例并设置所需的值。 您可以使用
Mock.Get()
配置任何方法:

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

它们也有相同的功能,但对于具有大量属性和方法的更复杂的服务,我认为
Mock.of
更具可读性

基于上述答案,我猜当您主要想要模拟属性时,
Mock.of()
更容易,而当您想要模拟方法等时,
Mock
更容易

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

以下是答案-只有当
IsoService
具有
IsActive
DelayTime
的设置器时,
Mock.Of()的示例代码才有效。如果没有,则如下声明:
var mockService=Mock.Of(mockService=>mockService.IsActive==true&&mockService.DelayTime==5000)
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;
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"),
});