2017-09-22 83 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