2017-09-26 46 views
2

我在嘲笑一個C函數庫(..ughh),其中包含以「帶指針的結構」爲參數的函數。我的目標是對這些指針指向的數據做一些期望。庫函數立即消耗它們的參數。即在函數被調用後,這些結構可能會超出範圍。更好的方法來嘲弄需要直接消費參數的函數

代碼:

struct A 
{ 
    B* somePointer; 
} 

class ClassUnderTest 
{ 
public: 
    ClassUnderTest() 
    { 
     B arbitraryStruct; 
     A structArg; 
     structArg.somePointer = &arbitraryStruct; 
     C_LibraryFunction(&A); 
    } 
}; 

我的解決方案是通過定義GTEST '動作' 來保存參數。在這個動作中將arbritraryStruct保存到一些全球化的地方,並且做我的期待魔術。例如

B arbitraryStruct; 
ACTION(captureB) 
{ 
    const A* a= arg0; 
    arbitraryStruct = *a->somePointer; 
} 

Test(TestClassUnderTest, testIt) 
{ 
    EXPECT_CALL(clibrary, 
    C_libraryFunction(testing::_)).WillOnce(DoAll(captureB()); 
    ClassUnderTest classUnderTest; 

    EXPECT_EQ(bla, B.arbitraryStruct); 
} 

它的工作原理,但它感覺有點全面。這個庫有很多調用,我需要模擬一些包含複雜結構。作爲一個懶惰的程序員,感覺這可以以更好的方式完成。任何人都可以想出更好的方法嗎?

謝謝!

回答

1

更好的辦法是不是這樣做。相反,你應該使用這些函數創建一個類,然後模擬該類。這個類應該儘可能簡單,以防止可能的錯誤。

例如:

struct MyIface { 
    virtual ~MyIface(){} 

    virtual void Clog() = 0; 
}; 

struct VeebleFitzer { 
    VeebleFitzer() : a(funcA()) { 
    } 
    virtual void Clog() { 
    funcX(a); 
    funcY(); 
    } 

    int a; 
}; 

然後使用某種依賴注入的傳遞對象,以任何需要的地方。


你總是可以創建功能測試,在您使用真正的資源(包括「真實」,而不是嘲笑,功能),對代碼進行測試。

+0

感謝您的意見!你完全正確,它的方式更清晰,定義一個接口來抽象出一個外部組件(在我的例子中是一個vulkan API)。現在我想起來了,我想要做的就是實際上將這個「轉換層」也放在測試中。也許不是一個好主意,繼續這條道路...這裏的挑戰是,在一些部分的表現是非常關鍵的,我不知道我可以保持在這方面的簡單,但這是另一個討論 –

+0

@SvenRademakers它取決於你想要什麼去做。功能測試應該做你想做的 - 用gtest用真實函數編寫測試(不要模擬它們)。如果你想測試上面的功能,那麼在下面進行單元測試和模擬功能。 –