动态DLL加载和googletest

时间:2016-01-22 09:45:10

标签: c++ dll googletest

我有几个基于MFC的项目(DLL)。我想在里面添加一些GTest / GMock测试。

我需要用最小的efford来做,所以ma计划是:

  1. 将测试文件添加到每个库并将其链接到gmock.lib
  2. 准备一个可执行文件,它将使用最小的main()动态加载所需的dll,如下所示:

    int main(int argc, char** argv)
    { 
        LoadLibrary(argv[1]);
        testing::InitGoogleMock(&argc, argv);
    
        const int status = RUN_ALL_TESTS();
    
        return status;
    }
    
  3. 问题是我的exe文件看不到加载库中的测试(dll被加载并初始化肯定)。输出是:

    [==========] Running 0 tests from 0 test cases.
    [==========] 0 tests from 0 test cases ran. (0 ms total)
    [  PASSED  ] 0 tests.
    

    似乎我应该以某种方式将测试从dll文件引入exe,但我找不到任何信息。 我的方法好吗?或者还有其他简单的方法?

1 个答案:

答案 0 :(得分:4)

将在编译时确定将要执行的测试。你正在做的只是在运行时使用显式DLL加载(函数LoadLibrary)将DLL加载到进程地址空间。

首先,我建议您根本不要在DLL项目中添加测试。单元测试代码不需要在将部署到最终用户的DLL中。另一个问题是,当您使用显式DLL加载时,您必须从DLL显式检索函数的地址并使用它来调用函数:

https://msdn.microsoft.com/en-us/library/784bt7z7.aspx

这不适合您的需要。你应该做的是以下几点:

  1. 将测试(使用所有所需DLL中的函数)添加到项目中,该项目将构建将从所有DLL运行单元测试的可执行文件。
  2. 为函数和类(来自所有需要的DLL)添加头文件的路径,作为构建此可执行文件的项目的附加包含目录。
  3. 将此可执行文件链接到gmock.lib
  4. 使用dllimport存储类属性设置隐式DLL加载,因此您不必编写显式获取将在单元测试中使用的DLL函数地址的代码。
  5. 有关隐式DLL加载的更多信息,请参阅:

    https://msdn.microsoft.com/en-us/library/d14wsce5.aspx

    编辑:

    由于切换到隐式链接不是您的选择,请以这种方式修改您的方法:

    首先,为每个DLL添加一个运行单元测试的附加导出函数:

    void runTests(int argc, char *argv[])
    {
        testing::InitGoogleMock(&argc, argv);
        const int status = RUN_ALL_TESTS();
    }
    

    然后,在可执行文件的main函数中,循环遍历所有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);
        }
    }