2017-09-22 41 views
0

我試圖單元測試的HTTP API寫在C++:懲戒常量值測試

void getLogNames(Request & req, Response & res) 
{ 
    vector<string> files = getFilesInDirectory(LOG_LOCATION, ".log", false); 
    json response(files); 
    res.send(response); 
} 

的問題是,LOG_LOCATIONcommon.h包括在內,是const,並且不能由我的測試中被改變代碼:

const std::string LOG_LOCATION = "/var/log" 

我試圖在文件上這樣做:

#ifdef UNIT_TEST 
#include <common_mock.h> 
#else 
#include <common.h> 
#endif 

然而,common.h被列入了在被鏈接某些共享庫,我將不得不UNIT_TEST掛鉤添加到所有這些文件並重新構建共享庫以及,我寧願避免...

是有更簡單的方法,我可以做到這一點,一些#define技巧或什麼?

+2

'#define LOG_LOCATION std :: string {「/ some/other/location」}'? – nwp

+0

@nwp這仍然需要放在源文件的'UNIT_TEST'模擬頭中,對嗎? – RPGillespie

+1

看來你想要測試'getLogNames':提供'getFilesInDirectory()'的模擬實現,並將其鏈接到測試。 –

回答

1

那麼,你可以嘗試const_cast指向你的LOG_LOCATION的指針,但它是骯髒和不可靠的解決方案,可能會導致段錯誤。例如:

original_file.h

#include <iostream> 

const std::string LOG_LOCATION = "/var/log"; 

int func() { 
    std::cout << LOG_LOCATION << std::endl; 
} 

unit_test.cpp

#include "test.h" 

void someUnitTest() { 
    const std::string* cs = &LOG_LOCATION; 

    std::string* s = const_cast<std::string*>(cs); 
    *s = "NEW_VALUE"; 

    std::cout << *s; 
} 

int main() { 
    someUnitTest(); 
} 

此代碼可能在某些情況下工作(即此成功編譯和GCC但只爲工作類對象類型 - 它會像int一樣使用構建類型崩潰),但可能隨不同的編譯器,平臺或優化級別而改變。

推薦的方法將重新設計您的應用程序並使用依賴注入,例如將您的函數調用包裝在類中,並將此位置設置爲可設置的成員。

0

爲什麼不改變你的類來接收它的構造函數中的日誌位置?通過對它進行硬編碼(從測試的角度來看,宏是等價的硬編碼),故意讓你的類變得不易測試。

+0

你是什麼意思「我的班」?這是用戶可能從瀏覽器調用的HTTP API的回調函數。 – RPGillespie