动态 dll 加载和 googletest
Dynamic dll load and googletest
我有几个基于 MFC 的项目 (DLL)。我想在里面添加一些 GTest/GMock 测试。
我需要以最小的努力完成它,所以我的计划是:
- 将测试文件添加到每个库并 link 它针对 gmock.lib
准备一个单独的可执行文件,它会像这样用最少的 main() 动态加载所需的 dll:
int main(int argc, char** argv)
{
LoadLibrary(argv[1]);
testing::InitGoogleMock(&argc, argv);
const int status = RUN_ALL_TESTS();
return status;
}
问题是来自已加载库的测试对我的 exe 文件不可见(dll 确实已加载和初始化)。输出为:
[==========] Running 0 tests from 0 test cases.
[==========] 0 tests from 0 test cases ran. (0 ms total)
[ PASSED ] 0 tests.
看来我应该以某种方式将测试从 dll 文件引入到 exe 中,但我找不到任何信息。
我的方法可以吗?或者也许还有其他简单的方法?
将要执行的测试在编译时确定。您正在做的只是在 运行 时间使用显式 DLL 加载(函数 LoadLibrary
)将 DLL 加载到进程地址 space。
首先,我建议您根本不要向您的 DLL 项目添加测试。单元测试代码无需位于将部署给最终用户的 DLL 中。另一个问题是,当您使用显式 DLL 加载时,您必须从 DLL 中显式检索函数地址并使用它来调用函数:
https://msdn.microsoft.com/en-us/library/784bt7z7.aspx
这不适合你想要的。你应该做的是:
- 将测试(使用来自所有所需 DLL 的函数)添加到将构建可执行文件的项目,该可执行文件将 运行 来自所有 DLL 的单元测试。
- 添加函数的头文件路径和 classes(来自所有需要的 DLL)作为构建此可执行文件的项目的附加包含目录。
- Link 这个可执行文件到
gmock.lib
- 使用
dllimport
存储 class 属性设置隐式 DLL 加载,因此您不必编写代码来显式获取 DLL 中将在单元测试中使用的函数地址。
有关隐式 DLL 加载的详细信息,请参阅:
https://msdn.microsoft.com/en-us/library/d14wsce5.aspx
编辑:
由于切换到隐式链接不适合您,因此请修改您的方法:
首先,向每个 DLL 添加一个额外的导出函数,运行s 单元测试:
void runTests(int argc, char *argv[])
{
testing::InitGoogleMock(&argc, argv);
const int status = RUN_ALL_TESTS();
}
然后,在可执行文件的主函数中,遍历所有 DLL 并使用以下代码为每个 DLL 执行导出的函数:
HMODULE hDLL = LoadLibraryA("MyDLL");
if(hDLL != NULL)
{
fpRunTests runTestsFun = (fpRunTests)GetProcAddress(hDLL, "runTests");
if(!runTestsFun)
{
// Handle the error
FreeLibrary(hDLL);
}
else
{
// Call the function which runs tests
runTestsFun(argc, argv);
}
}
我有几个基于 MFC 的项目 (DLL)。我想在里面添加一些 GTest/GMock 测试。
我需要以最小的努力完成它,所以我的计划是:
- 将测试文件添加到每个库并 link 它针对 gmock.lib
准备一个单独的可执行文件,它会像这样用最少的 main() 动态加载所需的 dll:
int main(int argc, char** argv) { LoadLibrary(argv[1]); testing::InitGoogleMock(&argc, argv); const int status = RUN_ALL_TESTS(); return status; }
问题是来自已加载库的测试对我的 exe 文件不可见(dll 确实已加载和初始化)。输出为:
[==========] Running 0 tests from 0 test cases.
[==========] 0 tests from 0 test cases ran. (0 ms total)
[ PASSED ] 0 tests.
看来我应该以某种方式将测试从 dll 文件引入到 exe 中,但我找不到任何信息。 我的方法可以吗?或者也许还有其他简单的方法?
将要执行的测试在编译时确定。您正在做的只是在 运行 时间使用显式 DLL 加载(函数 LoadLibrary
)将 DLL 加载到进程地址 space。
首先,我建议您根本不要向您的 DLL 项目添加测试。单元测试代码无需位于将部署给最终用户的 DLL 中。另一个问题是,当您使用显式 DLL 加载时,您必须从 DLL 中显式检索函数地址并使用它来调用函数:
https://msdn.microsoft.com/en-us/library/784bt7z7.aspx
这不适合你想要的。你应该做的是:
- 将测试(使用来自所有所需 DLL 的函数)添加到将构建可执行文件的项目,该可执行文件将 运行 来自所有 DLL 的单元测试。
- 添加函数的头文件路径和 classes(来自所有需要的 DLL)作为构建此可执行文件的项目的附加包含目录。
- Link 这个可执行文件到
gmock.lib
- 使用
dllimport
存储 class 属性设置隐式 DLL 加载,因此您不必编写代码来显式获取 DLL 中将在单元测试中使用的函数地址。
有关隐式 DLL 加载的详细信息,请参阅:
https://msdn.microsoft.com/en-us/library/d14wsce5.aspx
编辑:
由于切换到隐式链接不适合您,因此请修改您的方法:
首先,向每个 DLL 添加一个额外的导出函数,运行s 单元测试:
void runTests(int argc, char *argv[])
{
testing::InitGoogleMock(&argc, argv);
const int status = RUN_ALL_TESTS();
}
然后,在可执行文件的主函数中,遍历所有 DLL 并使用以下代码为每个 DLL 执行导出的函数:
HMODULE hDLL = LoadLibraryA("MyDLL");
if(hDLL != NULL)
{
fpRunTests runTestsFun = (fpRunTests)GetProcAddress(hDLL, "runTests");
if(!runTestsFun)
{
// Handle the error
FreeLibrary(hDLL);
}
else
{
// Call the function which runs tests
runTestsFun(argc, argv);
}
}