2017-07-21 37 views
1

我正在使用gtest爲我的C++程序創建單元測試。在我的測試中,我不得不寫了很多檢查的是這樣的:C++ Google測試(gtest):如何創建自定義斷言並期待?

ASSERT_TRUE(myObject.IsValid()); 
EXPECT_EQ(myObject.GetSomeAttribute(), expectedValue); 

我必須寫兩個檢查,因爲如果我省略了ASSERT_TRUEmyObject正好是無效的,比myObject.GetSomeAttributre()呼叫崩潰。即使在測試中也不好。

我想是這樣編寫代碼:

EXPECT_XXX_EQ(myObject.GetSomeAttribute(), expectedValue); 

這行代碼應該做大致相同,原兩行(帶有可選的獎金,如果myObject是無效的,這會報, GetSomeAttribute()不會被調用,但測試將繼續運行)。

如何編寫這樣的自定義斷言/期望?

+0

[Custom C++ assert macro]的可能重複(https://stackoverflow.com/questions/5252375/custom-c-assert-macro) – Eddge

+1

爲什麼不修復代碼來檢查對象在getattribute調用中是否有效? – stark

+0

@stark原因有兩個:1.我無法修改GetSomeAttribute()2.即使我可以,這個方法可以做的最好的方法就是死掉,如果調用無效對象的話。 – lesnik

回答

2

Advanced Guide,我們可以看到有幾種方法可以做到這一點。

最簡單的方法是using assertions in a subroutine

template<typename T> 
void AssertAttributeEquals(MyObject const& obj, T value) { 
    ASSERT_TRUE(obj.IsValid()); 
    // googletest has the assumption that you put the 
    // expected value first 
    EXPECT_EQ(value, obj.GetAttribute()); 
} 

而且你可以調用它像這樣:

AssertAttributeEquals(myObject, expectedValue); 

雖然你可能需要使用SCOPED_TRACE獲得失敗更好的消息:

{ 
    SCOPED_TRACE("whatever message you want"); 
    AssertAttributeEquals(myObject, expectedValue); 
} 

或者,您可以use a function that returns an AssertionResult

template<typename T> 
::testing::AssertionResult AttributeEquals(MyObject const& obj, T value) { 
    if (!obj.IsValid()) { 
     // If MyObject is streamable, then we probably want to include it 
     // in the error message. 
     return ::testing::AssertionFailure() << obj << " is not valid"; 
    } 
    auto attr = obj.GetAttribute(); 

    if (attr == value) { 
     return ::testing::AssertionSuccess(); 
    } else { 
     return ::testing::AssertionFailure() << attr << " not equal to " << value; 
    } 
} 

這可以用於像這樣:

EXPECT_TRUE(AttributeEquals(myObject, expectedValue)); 

這第二個技術具有生產友好的錯誤消息的好處,即使你不使用SCOPED_TRACE