2017-04-24 60 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和最小起訂量,我建議:)