GMock 测试夹具在 Windows 上崩溃

GMock test fixture crashes on Windows

本文关键字:崩溃 Windows 测试 夹具 GMock      更新时间:2023-10-16

我是使用GMock框架的新手。但是,我有以下生产应用程序productionApp和测试应用程序testApp。我的生产应用程序运行良好。但是在夹具中执行第一个测试后,测试崩溃。

class IRegEditor
{
public:
    virtual bool Read(int&) = 0;
    virtual bool Write(const int&) = 0;
    virtual ~IRegEditor() {}
};
class RegEditorImpl : public IRegEditor
{
public:
    //use windows registry APIs instead
    //read returns values based on current time.
    //write fails for odd values.
    bool Read(int& i) { if (system_clock::now().time_since_epoch().count() % 2)                 
    return false; else { i = 10; return true; } }
    bool Write(const int& j) { if (j % 2) return false; else return true; }
};
class RegEditorMock : public IRegEditor
{
public:
    MOCK_METHOD1(Read, bool(int&));
    MOCK_METHOD1(Write, bool(const int&));
};
class RegEditTest : public ::testing::Test
{
protected:
    virtual void SetUp() {
        regEditor.reset(&regMock);
    }
    std::shared_ptr<IRegEditor> regEditor;
    RegEditorMock regMock;
};
class App
{
    std::shared_ptr<IRegEditor> regEdit;
public:
    //ctor to use in production
    App() :regEdit{ std::make_shared<RegEditorImpl>() }
    {}  
    //overloaded ctor to use for unit tests
    App(std::shared_ptr<IRegEditor> regEditor) : regEdit{ regEditor }
    {}
    bool Writer(const int& number)
    {
        if (regEdit->Write(number)) 
        { std::cout << "write passed" << std::endl; return true; }
        else 
        { std::cout << "write failed" << std::endl; return false; }
    }
    bool Reader(int& number)
    {
        if (regEdit->Read(number)) 
        { std::cout << "read passed" << std::endl; return true; }
        else { std::cout << "read failed" << std::endl; return false; }
    }
};
TEST_F(RegEditTest, writeFails)
{
    int number = 1;
    EXPECT_CALL(regMock, Write(number)).Times(1).WillOnce(Return(false));
    App testApp(regEditor);
    EXPECT_FALSE(testApp.Writer(number));
}
TEST_F(RegEditTest, writeSucceeds)
{
    int number = 2;
    EXPECT_CALL(regMock, Write(number)).Times(1).WillOnce(Return(true));
    App testApp(regEditor);
    EXPECT_FALSE(testApp.Writer(number));
}
int main(int argc, char** argv) {
    // The following line must be executed to initialize Google Mock
    // (and Google Test) before running the tests.
    ::testing::InitGoogleMock(&argc, argv);
    return RUN_ALL_TESTS();
}

我在运行测试时收到以下错误。它与GMock库的编译器设置兼容性有关吗?

Unhandled exception at 0x77639D71 (ntdll.dll)
A heap has been corrupted (parameters: 0x7766D8D0).

然后显示,它无法从 wntdll.pdb 加载符号。

以下生产应用按预期工作

int main()
{
    App productionApp;
    int num = 9;
    productionApp.Reader(num);
    productionApp.Writer(num);
    std::cin.get();
    return 0;
}

不能做regEditor.reset(&regMock);这使得regEditor拥有本地regMock,现在,由于regMock有两个所有者:它的自动存储持续时间,加上共享指针regEditor - 当范围结束时,内存已损坏。这与GMock或GTest版本或编译器设置或兼容性没有任何关系。这是因为我对shared_ptr的错误使用。感谢Jarod42和Angew的帮助。请参考如何使用shared_ptr从外部提供模拟对象?