2013-04-02 27 views
3

我對單元測試的高度可預測的Arrange Act Assert format有強烈的偏好。在Kiwi mocks上缺少驗證方法是否有解決方法?

由於獼猴桃不具備嘲笑明確的驗證聲明,它迫使一個不同的模式,像:

// Arrange 
Thing *mockThing = [CollaboratingClass mock]; 
TestedClass *sut = [[TestedClass alloc] initWithCollaborator:mockThing]; 

// Expect (collaboration expectations) 
[[[mockThing should] receive] someMessage]; 

// Act 
[mockArray someMethodInvolvingCollaborator]; 

// Assert (state expectations) 
[[sut.someProperty should] equal:someValue]; 

我知道驗證發生無論如何,但更喜歡能夠快速掃描測試,斷言和期望集中在一個可預測的地方。這很好地由mockito(及其Objective-C實現OCMockito)啓用,其中驗證步驟指定方法調用事件後,使預先步驟不必要。

我是一個親戚新西蘭人,所以我可能錯過了文檔中的某些東西。有沒有明確驗證獼猴桃模擬的方法?

回答

4

您提供關於排列法斷言有這樣說,關於模式的(強調)的利益鏈接:

優點:

  • ...
  • 使一些TestSmells更明顯:
    • 與「Act」代碼混合的斷言。
    • 試圖一次

特別是如果你的目標是要能夠快速掃描斷言測試過許多不同的事情的測試方法,我覺得你的例子會更好打散分成兩個測試案例:一個協作測試,以及一個單獨的測試,以瞭解對象狀態如何改變。

我實際上認爲這裏有第四步,具體到協作測試,這是期望。 Kiwi讓你Arrange,Expect,Act,其中OCMock實際上需要你添加第四個冗餘斷言步驟通過要求[mockThing verify]

我認爲這將是一個更好的辦法來建立這些測試:

__block TestedClass *sut; 
beforeAll(^{ 
    sut = [[TestedClass alloc] initWithCollaborator:mockThing]; 
} 

// Collaboration: Arrange, Expect, Act 
it(@"sends someMessage to mockThing", ^{ 
    // Arrange 
    Thing *mockThing = [CollaboratingClass mock]; 

    // Expect 
    [[[mockThing should] receive] someMessage]; 

    // Act 
    [mockArray someMethodInvolvingCollaborator]; 
} 

// State: Arrange, Act, Assert 
it(@"sets someProperty to the return value of someMethod", ^{ 
    // Arrange 
    NSString *expectedString = @"foo"; 
    Thing *mockThing = [CollaboratingClass mock]; 
    [[mockThing stubAndReturn:expectedString] someMessage]; 

    // Act 
    [mockArray someMethodInvolvingCollaborator]; 

    // Assert 
    [[sut.someProperty should] equal:expectedString]; 
} 

你在此設置獲得的好處是,如果你需要基於從合作者的返回值分支,只需添加一個測試,存根someMethod返回不同的結果,並進行了不同的說法:

it(@"sets someProperty to nil if someMethod returns baz", ^{ 
    // Arrange 
    Thing *mockThing = [CollaboratingClass mock]; 
    [[mockThing stubAndReturn:@"baz"] someMessage]; 

    // Act 
    [mockArray someMethodInvolvingCollaborator]; 

    // Assert 
    [sut.someProperty shouldBeNil]; 
} 

最後,我認爲獼猴桃是不是需要我們verify我們的測試雙打做我們一個忙。

+0

感謝您的深思。我完全同意我的例子在邏輯上是兩個單獨的測試。但我並沒有在這裏採用新西蘭方式的優點進行銷售。它導致協作測試和狀態測試具有不同的模式(AEA vs AAA),測試的真正內容(期望/斷言)具有不同的定位。這對快速掃描是不利的。驗證步驟可能是多餘的使用OCMock,但不是與OCMockito,這是我想到的最好的整體模式(將編輯問題,以澄清) – Cris

+0

接受理由,你已經有效地解釋了爲什麼答案是'不'(這是對任何問題的完美答案)。我仍然不太喜歡獼猴桃的做法,但這只是品味。 – Cris

+0

感謝您接受答案。最近我一直在想這個問題,並想知道最好的方法是什麼。如果獼猴桃允許採取任何一種方法,那麼肯定會很好,並且如果有必要,可以通過事後聲明進行明確驗證。 –

相關問題