2012-07-21 142 views
5

假設我有以下實體:嘲諷Guid.NewGuid()

public class User 
{ 
    public int Id { get; set; } 
    public string Username { get; set; } 
    public Guid UserGuid { get; set; } 
    public Guid ConfirmationGuid { get; set; } 
} 

而下面的接口方法:

void CreateUser(string username); 

實施應建立兩個新的GUID部分:一爲UserGuid,另一個爲ConfirmationGuid。他們應該通過將值設置爲Guid.NewGuid()來做到這一點。

我已經使用的接口抽象Guid.NewGuid():

public interface IGuidService 
{ 
    Guid NewGuid(); 
} 

所以只需要一個新的GUID時,我可以很容易地嘲笑這一點。但是我不確定如何在一個方法中模擬對同一方法的兩個不同調用,以便返回不同的值。

回答

9

如果您正在使用起訂量,你可以使用:

mockGuidService.SetupSequence(gs => gs.NewGuid()) 
    .Returns(...some value here...) 
    .Returns(...another value here...); 

我想你也可以做到以下幾點:

mockGuidService.Setup(gs => gs.NewGuid()) 
    .Returns(() => ...compute a value here...); 

不過,除非你只是提供返回內的隨機值功能,秩序的知識似乎仍然是重要的。

+0

但是,這不會假設我設置的實現中的屬性在一定的順序?這不是讓我感到擔憂嗎?換句話說,這些字段可以按任意順序設置,如果由於某種原因,我更改了這個順序而沒有更新我的測試,我的測試應該仍然通過。 – 2012-07-21 04:13:12

+0

那麼......你進入狀態與行爲測試有點相似。我不確定除了做出有關呼叫訂單的知識假設之外,還有其他答案。 – 2012-07-21 04:23:01

+3

如果我理解正確,你不想擁有'Assert.AreEqual(guid1,user.UserGuid); Assert.AreEqual(guid2,user.ConfirmationGuid);如果更改了賦值順序,則失敗。相反,你應該使用某種獨立於順序的集合斷言(在nunit和mstest中都可用):'CollectionAssert.AreEquivalent(new [] {guid1,guid2},new [] {user.UserGuid,user.ConfirmationGuid}) ;' – 2012-07-21 05:04:21

4

如果你不能像@ Matt的例子那樣使用Moq,那麼你可以構建你自己的類,它將做基本相同的事情。

public class GuidSequenceMocker 
{ 
    private readonly IList<Guid> _guidSequence = new[] 
                { 
                 new Guid("{CF0A8C1C-F2D0-41A1-A12C-53D9BE513A1C}"), 
                 new Guid("{75CC87A6-EF71-491C-BECE-CA3C5FE1DB94}"), 
                 new Guid("{E471131F-60C0-46F6-A980-11A37BE97473}"), 
                 new Guid("{48D9AEA3-FDF6-46EE-A0D7-DFCC64D7FCEC}"), 
                 new Guid("{219BEE77-DD22-4116-B862-9A905C400FEB}") 
                }; 
    private int _counter = -1; 

    public Guid Next() 
    { 
     _counter++; 

     // add in logic here to avoid IndexOutOfRangeException 
     return _guidSequence[_counter]; 
    } 
}