2017-04-24 139 views
0

我使用起订量在C#中做一些单元测试/ BDD测试两个对象,我常常产生两次对同一对象的需要(因为它会在字典中可能使用的)。或者99%的东西是一样的,但只是一个不同的ID。生成的相同模拟

有没有一种方法来“克隆”素定义是什么?或者要生成两个具有相同定义的对象?

+1

写方法与参数建立模拟 –

回答

0

你应该创建一个构建在一些参数需要构建模拟对象的辅助方法。

[Test] 
public void MyTest() 
{ 
    Mock<ITestObject> myMock = CreateObject(1); 
    ITestObject obj = myMock.Object; 
} 

private Mock<ITestObject> CreateObject(int id) 
{ 
    Mock<ITestObject> mock = new Mock<ITestObject>(); 
    mock.SetupGet(o => o.ID).Returns(id); 
    return mock; 
} 

private interface ITestObject 
{ 
    int ID { get; set; } 
} 
+0

是的,我做了这个,如果有完全相同的模拟,是否必须创建两个模拟? – J4N

+0

模拟类型没有任何复制/克隆功能,也没有标记为[[Serializable]],所以我认为这是最好的解决方案。 – Matthiee

+0

好吧,我只是想知道,影响并不大,但我会发现这更好。 – J4N

0

如果你只是需要一个数据集合来进行单元测试,你也可以考虑类似AutoFixture的东西。如果你想模拟课程,它可以和Moq一起工作。你教AutoFixture如何创建YourClass,甚至可以设置规则,如“我的ID应该是大写字母的字符串,不超过X的数量”。

然后,你只需使用autofixture。

var fixture = new Fixture(); 
var tetsClasses = fixture.CreateMany<TestClass>(); 

这真的只是给你一个想法。你可以做得更多,但更多,它和Moq的表现非常好。

另一种方法是使用数据生成器模式来创建自己的数据。因此,您可以从简单的事情开始,随着您找到需要构建数据的新边缘案例,继续添加它。只需在其上构建流畅的API并根据需要构建数据。

internal class TestClassBuilder<T> : where T : TestClass 
{ 
    int Id {get; set;} 

    public T WithId(int id) 
    { 
    this.Id = id; 
    return this; 
    } 

    public virtual T Build() 
    {  
     return new T() 
     { 
      if(this.Id) 
       Id = this.Id; // if you chose to set it, then assign it 
      else 
      Id = GetRandomId() // you can figure a solution here 
     } 
    } 
} 

然后调用它像:

var stubOne = TestClassBuilder.WithId(1).Build(); 

你可以扩展它,如果你想建立一个列表。

我喜欢上的数据建设者流利的API,因为你可以开始创建方法告诉你的故事,它让你的安排部分干净利落。 例子:

var UnderAgeCustomer = new CustomerBuilder 
         .UnderAge 
         .WithFakeId 
         .InACrowd 
         .LooksYoung 
         .Build() 

你甚至可以添加在

public static implicit operator T(TestClassBuilder<T> builder) 
{ 
    return builder.Build(); 
} 

而且你不需要使用.Build()部分所有的时间(我认为构建增加了不必要的噪音)。只是不要尝试将其分配给var,它将无法工作。

TestClass MockTwo = TestClassBuilder.WithId(2); 

我会说,你也可以使用一个固定模式来追踪这一切......但与databuilder之间,你不妨使用AutoFixture和最小起订量,我建议:)