2013-03-07 49 views
1

我想用谷歌測試測試一個函數。鏈接器錯誤 - 鏈接兩個「應用程序」類型的項目,以便使用谷歌測試

看來,一切都設置正確,它建立和執行沒有gtest罰款...(有一點複雜的代碼,所以我不能列出所有的源文件在這裏,但沒有添加gtest,這些文件鏈接正確,並按照它們的運行方式運行)。

這是一個應用程序類型項目。它有一些庫依賴關係......無關緊要。

測試項目作爲獨立項目添加到解決方案中。它將測試的項目作爲依賴項。測試項目的.h文件只指向gtest ... .cpp(不是main,這是標準的InitGoogleTest主)添加它自己的頭文件,測試項目的頭文件,並且具有如下所示的測試。

當項目構建時,即使它是應用程序,也會自動創建TestedProject.lib。我已將TestedProject.lib作爲庫依賴項添加到TestProject(在Link中)。

Class x 
{ 
public: 
    x(){} // I didn't really need this, I only added the class so I have access to 
    ~x(){}; // non-class methods with gtest - but it still doesn't work 
    bool myFunction(std::string a, double b, bool c); 
}; 

實現:

bool x::myFunction(std::string a, double b, bool c) 
{ 
    // implementation 
    return false; 
} 

somewhere_else 
{ 
    x x_instance; 
    y = x_instance.myFunction("a", 1, false); // works, all builds, executes, life is great 
} 

添加單元測試:

class TheTest : public ::testing::Test 
{ 
protected: 
    x x_instance; 
}; 

TEST_F(TheTest, Fail) 
{ 
    EXPECT_FALSE(x_instance.myFunction("a", 1, false));  
} 

不建。鏈接出錯(修改,像上面的示例代碼,以簡化的名字,我希望我沒有搞砸內容)

Error 2 error LNK2019: unresolved external symbol 
"public: bool __thiscall x::myFunction(class std::basic_string<char,struct std::char_traits<char>,double,bool)" 
([email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]) 
referenced in function "private: virtual void __thiscall TheTest_Fail_Test::TestBody(void)" 
([email protected][email protected]@EAEXXZ) C:\path\file.obj 

我已經這樣做過 - 解決鏈接錯誤 - 寫了幾個測試與谷歌測試 - 但我看不到任何東西丟失。

作爲測試,我寫了一個小

INT測試(){返回4;}在頭文件 ,在類聲明...

然後,代替測試與 EXPECT_EQ(x.test(),4);

它工作。大。但這意味着將所有測試過的代碼放在一個文件中,一個cpp或其他東西......這簡直是不合理的。這個應用程序項目中有幾個文件。

我該如何解決這個問題?如何使Google測試鏈接並使用包含頭文件和實現文件的類進行測試?當這個頭文件/實現在不同的項目中時,「Application」類型?

唯一類似的問題,我發現,到目前爲止:C++ linking issue on Visual Studio 2008 when crosslinking different projects on same solution

請幫我找到一個解決方案。

+0

通常你會有一個庫(或一些庫),它們構成了你自己的代碼的大部分,而一個只有'main'函數的exe /應用程序鏈接你的lib(s)。通過這種方式,您可以使用另一個'main'和一堆測試代碼(如果需要的話,可以使用多個文件)來另一個項目,這些代碼也*鏈接您的lib。您不應該期望能夠將2個應用程序與2個'main'鏈接起來。 – Fraser 2013-03-08 09:01:38

+0

謝謝。這就是我最終實現它的原因,只要我完成了問題的提問,確實 - 當我找到我添加的鏈接時,鏈接幫助我找出了問題。我不得不創建一個單獨的項目,只提取一個小的main()放入它。我確實希望能夠將2個應用程序與main()...鏈接起來,並且花了很長時間才弄清楚我不能。我確定在某處有一個「鏈接錯誤手冊」,或者「什麼可以被測試的手冊」,或者「其他人嘗試和失敗的東西,所以儘量不要犯同樣的錯誤」手冊...我想閱讀它。 – Thalia 2013-03-08 20:32:51

+0

對 - 我也是!編譯器錯誤通常比鏈接器更容易解決。 – Fraser 2013-03-08 21:02:10

回答

1

因此,我將有一個答案:

我有2個解決方案,以我的問題:

1)將相關應用項目2個項目,一個將成爲庫,大部分代碼;另一個將是一個應用程序,包含一個調用真實代碼入口點的小型main()(如參數解析方法或其他)。

然後,我可以添加一個單元測試項目 - 來測試lib。

2)不要拆分項目。添加一個gtest項目,不要創建任何依賴項。將要測試的文件添加到gtest項目中。 gtest項目將會是一個獨立的可執行文件......它需要所有的快樂。 (優點:不依賴於測試)

我更喜歡第一個版本。

2

有一個又一個解決方案,我更喜歡,因爲這意味着你能避免改變你的主要項目:

,主要項目上添加一個「後生成的行動」,以創建一個靜態庫的確切相同的源文件。 然後,您可以簡單地將此依賴項添加到您的gtest項目中。

每次你編譯你的主項目,它都會建立應用程序和靜態庫。

這樣您就不必創建第三個項目並保持配置同步。

希望它有幫助。

+1

具體的設置應該是:打開主項目屬性,選擇Build Event-> Post-Build Event選項卡。使用命令* lib/NOLOGO /OUT:"$(TargetPath).lib「」$(ProjectDir)\ $(Configuration)\ * .obj「*以便這將生成一個$(ProjectName).exe.lib文件.exe文件,它對於單元測試項目的靜態鏈接很有用。 – yc2986 2016-08-23 22:49:56

0

還有另一種解決方案。

只需爲Google測試框架創建一個新項目。 (當然,在您現有的應用程序解決方案下)。

然後,確保您的所有Google測試框架安裝正確後。 (您可以在新創建的解決方案中測試它)

手動在您的主項目中包含要測試的代碼(使用添加 - >現有項目),然後您可以測試代碼而不生成其他庫。

這很好的一部分是,當你測試一些需要DLL的應用程序時,它需要應用程序使用多線程調試DLL。 (在您的項目屬性設置中,轉到C/C++ - >代碼生成 - >運行時庫,看看你得到了什麼)

谷歌測試框架使用一個非常不同的RunTime庫(多線程調試(/ MTd)) 。

在鏈接階段,編譯器會哭,它有一些困難,從應用程序生成的庫與多線程DLL和谷歌框架的lib(這是多線程)鏈接。

通過這種方式,您可以避免兩個項目的依賴性問題。 (一個用於/ Mtd,另一個用於/ Md)

+0

您的解決方案與我在5年前發佈的第二個選項相同。 – Thalia 2017-01-18 17:36:11

+0

嗯....我應該刪除我的帖子? – 2017-01-20 01:27:58