Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google模拟全局模拟对象内存泄漏 我使用VS2005和C++进行单元测试,使用谷歌模拟。 我在单元测试中有一个全局自由函数,我使用以下代码模拟自由函数: NiceMock <MockA> mockObj; struct IFoo { virtual A* foo() = 0; virtual ~IFoo() {} }; struct FooMock : public IFoo { FooMock() {} virtual ~FooMock() {} MOCK_METHOD0(foo, A*()); }; FooMock fooMock; // foo() implementation A* foo() { return fooMock.foo(); }_C++_Unit Testing_Memory Leaks_Heap_Googlemock - Fatal编程技术网

Google模拟全局模拟对象内存泄漏 我使用VS2005和C++进行单元测试,使用谷歌模拟。 我在单元测试中有一个全局自由函数,我使用以下代码模拟自由函数: NiceMock <MockA> mockObj; struct IFoo { virtual A* foo() = 0; virtual ~IFoo() {} }; struct FooMock : public IFoo { FooMock() {} virtual ~FooMock() {} MOCK_METHOD0(foo, A*()); }; FooMock fooMock; // foo() implementation A* foo() { return fooMock.foo(); }

Google模拟全局模拟对象内存泄漏 我使用VS2005和C++进行单元测试,使用谷歌模拟。 我在单元测试中有一个全局自由函数,我使用以下代码模拟自由函数: NiceMock <MockA> mockObj; struct IFoo { virtual A* foo() = 0; virtual ~IFoo() {} }; struct FooMock : public IFoo { FooMock() {} virtual ~FooMock() {} MOCK_METHOD0(foo, A*()); }; FooMock fooMock; // foo() implementation A* foo() { return fooMock.foo(); },c++,unit-testing,memory-leaks,heap,googlemock,C++,Unit Testing,Memory Leaks,Heap,Googlemock,在TearDown()中,我删除了全局mock对象fooMock virtual TearDown(){ delete &fooMock; } 当我运行代码时,我得到以下错误 错误:xyz.instA中存在内存泄漏 而且, 0个空闲块中有0个字节。 -在-1个正常块中有61个字节。 7个CRT块中有68个字节。 0个忽略块中有0个字节。 0个客户端块中有0个字节。 使用的最大数字:11025字节 总分配:50602字节 有人能告诉我这里发生了什么事吗?如果我不删除f

TearDown()
中,我删除了全局mock对象
fooMock

virtual TearDown(){  
    delete &fooMock;  
}  
当我运行代码时,我得到以下错误

错误:xyz.instA中存在内存泄漏

而且,
0个空闲块中有0个字节。
-在-1个正常块中有61个字节。
7个CRT块中有68个字节。
0个忽略块中有0个字节。
0个客户端块中有0个字节。
使用的最大数字:11025字节
总分配:50602字节

有人能告诉我这里发生了什么事吗?如果我不删除
fooMock
,我会得到错误“fooMock应该被删除,但永远不会被删除”,或者检测到堆损坏。
从这个错误中,我可以看出我的堆在某个地方被错误地处理了,但我找不到重点。我也尝试过一步一步地调试它


一些帮助真的很棒!:)

问题似乎在于您正在实例化FooMock的全局实例。Googlemock/googletest期望在测试主体或测试夹具类中定义模拟

在上面的示例中,您只需在测试中实例化fooMock:

TEST(..., instA) {

    FooMock fooMock;
    // ...
}

看起来问题在于您正在实例化FooMock的全局实例。Googlemock/googletest期望在测试主体或测试夹具类中定义模拟

在上面的示例中,您只需在测试中实例化fooMock:

TEST(..., instA) {

    FooMock fooMock;
    // ...
}
如上所述:

Googlemock/googletest期望在测试主体或测试夹具类中定义模拟

其背后的思想解释如下:

当它被销毁时,您友好的模拟对象将自动验证是否满足了对它的所有期望,如果不满足,将生成Google测试失败。这很方便,因为它让你少担心一件事。也就是说,除非您不确定您的模拟对象是否将被销毁

在您的情况下,fooMock是一个全局变量(正如您所说,它必须保持这种方式),因此在每次测试之后,您只需要运行手动验证:

    using ::testing::Mock;

    TEST(..., instA) 
    {
       ASSERT_TRUE(
           Mock::VerifyAndClearExpectations(
            &fooMock));
    }
由于它是一个全局变量,您也可以执行以下操作:

Mock::AllowLeak(&fooMock);
和中的更多详细信息:

如前所述:

Googlemock/googletest期望在测试主体或测试夹具类中定义模拟

其背后的思想解释如下:

当它被销毁时,您友好的模拟对象将自动验证是否满足了对它的所有期望,如果不满足,将生成Google测试失败。这很方便,因为它让你少担心一件事。也就是说,除非您不确定您的模拟对象是否将被销毁

在您的情况下,fooMock是一个全局变量(正如您所说,它必须保持这种方式),因此在每次测试之后,您只需要运行手动验证:

    using ::testing::Mock;

    TEST(..., instA) 
    {
       ASSERT_TRUE(
           Mock::VerifyAndClearExpectations(
            &fooMock));
    }
由于它是一个全局变量,您也可以执行以下操作:

Mock::AllowLeak(&fooMock);

和中的更多细节:

所以我偶然发现了这个问题,想不出办法。但作为一名软件工程师,我需要找到一个解决方案。这就是我所做的

假设要模拟队列。要模拟的一个函数是“出列”。我假设您希望将整数出列以保持简单,因为我想演示如何在没有内存泄漏的情况下进行全局模拟

class QueueInterface {
    public:
        virtual ~QueueInterface() {};
        virtual int dequeue() = 0;
};

class QueueMock : public QueueInterface {
    public:
        virtual ~QueueMock() {};
        MOCK_METHOD(int, dequeue, (), (override));
};

// Instead of a global object, have a global pointer
QueueMock *globalQueue;

class TestFixture : public ::testing::Test {
    protected:
        QueueMock mockedQueue;

        void SetUp() {
            globalQueue = &mockedQueue; // Point the global pointer to this queue
        }

        void TearDown() {
            globalQueue = NULL;
        }
}

// Now you can use this global queue pointer in free function or
// C style functions and override the existing implementations.
// This way you can mock a global object.

int dequeueFromQueue() {
   return globalQueue->dequeue();
}

TEST_F(TestFixture, DEQUEUE_TEST) {
    // Write your test here to use global queue pointer
    // Deref pointer to get mocked object
    EXPECT_CALL(*globalQueue, dequeue);
}
这样,无论何时执行新测试,都会分配成员变量mockedQueue,然后在测试结束时取消分配。globalQueue每次都会指向每个测试的成员实例


希望这有帮助!:)

所以我偶然发现了这个问题,想不出办法。但作为一名软件工程师,我需要找到一个解决方案。这就是我所做的

假设要模拟队列。要模拟的一个函数是“出列”。我假设您希望将整数出列以保持简单,因为我想演示如何在没有内存泄漏的情况下进行全局模拟

class QueueInterface {
    public:
        virtual ~QueueInterface() {};
        virtual int dequeue() = 0;
};

class QueueMock : public QueueInterface {
    public:
        virtual ~QueueMock() {};
        MOCK_METHOD(int, dequeue, (), (override));
};

// Instead of a global object, have a global pointer
QueueMock *globalQueue;

class TestFixture : public ::testing::Test {
    protected:
        QueueMock mockedQueue;

        void SetUp() {
            globalQueue = &mockedQueue; // Point the global pointer to this queue
        }

        void TearDown() {
            globalQueue = NULL;
        }
}

// Now you can use this global queue pointer in free function or
// C style functions and override the existing implementations.
// This way you can mock a global object.

int dequeueFromQueue() {
   return globalQueue->dequeue();
}

TEST_F(TestFixture, DEQUEUE_TEST) {
    // Write your test here to use global queue pointer
    // Deref pointer to get mocked object
    EXPECT_CALL(*globalQueue, dequeue);
}
这样,无论何时执行新测试,都会分配成员变量mockedQueue,然后在测试结束时取消分配。globalQueue每次都会指向每个测试的成员实例


希望这有帮助!:)

我遇到了同样的问题,下面是解决方案(不确定内部到底发生了什么,因为全局模拟obj最终将被破坏)

std::unique_ptr ptrMockObj(新的FooMock())

在测试用例结束时,删除mock obj ptr

测试(…,instA) { ... ptrMock.Obj.reset()
}

我遇到了同样的问题,下面是解决方案(不确定内部到底发生了什么,因为全局模拟obj最终将被销毁)

std::unique_ptr ptrMockObj(新的FooMock())

在测试用例结束时,删除mock obj ptr

测试(…,instA) { ... ptrMock.Obj.reset()
}

您不能删除
fooMock
,因为它没有动态存储
fooMock应该被删除,但永远不会被删除
或检测到的
堆损坏
要么由于显示的代码(减去删除)而未报告,要么错误报告器有缺陷。@user2079303:我删除了删除语句,现在我有了以下错误:…\xyzTest.cpp(73):错误:此模拟对象(用于测试xyzTest.instA)应该删除,但决不删除。其地址为“0053DFA0”。错误:在程序出口处发现1个泄漏的模拟对象。代码中SetUp()方法的第73行点:EXPECT_调用(fooMock,foo()).Times(1).WillOnce(Return(&mockObj));嗯,我对谷歌不太熟悉。可能需要动态分配模拟对象?这取决于场景。但我已经试过了,给出了与我原来帖子中相同的错误。也许我在嘲弄的时候做错了什么。你可能的复制品一定不能