gpt4 book ai didi

c++ - 在 gmock 中使用指向带有 EXPECT_CALL 的模拟对象的指针会导致段错误或默认处理程序启动

转载 作者:行者123 更新时间:2023-12-02 10:30:50 25 4
gpt4 key购买 nike

我正在使用 gmock 来模拟一个底层库,同时我正在测试我的包装器。我注意到 gmock 需要预先定义模拟对象。我想要的是传递一个指向模拟对象的指针。如果测试错误处理所需的对象是动态创建的,则它不起作用。

引用:gmock/google-mock issues warning and fails the test with mocking exceptions
代码:

测试/mock_turtle_test.cc

#include "mock_turtle.h"
#include "../painter.h"
#include <gtest/gtest.h>

using ::testing::_;
using ::testing::AtLeast;
using ::testing::Return;
ACTION(MyException)
{
throw(error_k());
}
TEST(PainterTest, CanDrawSomething) {
Painter painter;
EXPECT_CALL(*(painter.getTurtle()), PenDown())
.Times(AtLeast(1))
.WillOnce(MyException())
.WillRepeatedly(Return(5));
EXPECT_TRUE(painter.DrawCircle(0, 0, 10));
}

int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

inc/mock_turtle.h
#pragma once
#include <cstdlib>
#include "turtle.h"
#include <gmock/gmock.h>

class Turtle : public FakeTurtle{
public:
using FakeTurtle::FakeTurtle;
MOCK_METHOD((void), PenUp, ());
MOCK_METHOD((int), PenDown, ());
MOCK_METHOD((void), Forward, (int distance));
MOCK_METHOD((void), Turn, (int degrees));
MOCK_METHOD((void), GoTo, (int x, int y));
MOCK_METHOD((int), GetX, ());
MOCK_METHOD((int), GetY, ());
};

公司/乌龟.h
#pragma once

class FakeTurtle {

public:
virtual ~FakeTurtle() {}
virtual void PenUp() {};
virtual int PenDown() {};
virtual void Forward(int distance) {};
virtual void Turn(int degrees) {};
virtual void GoTo(int x, int y) {};
virtual int GetX() const {};
virtual int GetY() const {};

};

画家.h
#pragma once
#include "turtle.h"
#include <cerrno>

class error_k
{
public:
error_k() : errnum(EAGAIN){}
int num() const
{
return errnum;
}
private:
int errnum;
};

class Painter
{
Turtle* turtle;
public:
Painter() : turtle(new Turtle){}
//Painter(){}
Turtle** getTurtle(){
return &turtle;
}
bool DrawCircle(int, int, int){
int rep = 10;
int ret = 0;
delete turtle;
turtle = new Turtle;
do{
try{
std::cout << "calling PenDown() : rep = " <<
rep << " , ret = " << ret << std::endl;
ret = turtle->PenDown();
if(ret > 0)
return true;
}catch(error_k err )
{
std::cout << "Caught Exception (" <<
err.num() << "): rep = " <<
rep << " , ret = " << ret << std::endl;

delete turtle;
turtle = new Turtle();
}
}while(rep-- > 0 && ret == 0);
return false;
}
~Painter(){
delete turtle;
}
};

CmakeLists.txt
cmake_minimum_required(VERSION 2.6)

# Locate GTest
find_package(GTest REQUIRED)
find_package(PkgConfig)
message(STATUS "gtest found: " ${GTEST_FOUND})
pkg_check_modules(GMOCK "gmock" REQUIRED)
message(STATUS "gmock found: " ${GMOCK_FOUND})

include_directories(${GTEST_INCLUDE_DIRS})

# Link runTests with what we want to test and the GTest and pthread library
add_executable(runTests test/mock_turtle_test.cc)
target_link_libraries(runTests ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} gmock gmock_main gtest gtest_main)
target_include_directories(runTests SYSTEM PRIVATE inc)
add_test(NAME runTests COMMAND runTests)
enable_testing()

输出:
$ make ; ./runTests 
Scanning dependencies of target runTests
[ 50%] Building CXX object CMakeFiles/runTests.dir/test/mock_turtle_test.cc.o
[100%] Linking CXX executable runTests
[100%] Built target runTests
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from PainterTest
[ RUN ] PainterTest.CanDrawSomething
/home/preetam/Desktop/gmock/cpp_mock_ptr/test/mock_turtle_test.cc:16: Failure
Actual function call count doesn't match EXPECT_CALL(**tt, PenDown())...
Expected: to be called at least once
Actual: never called - unsatisfied and active
calling PenDown() : rep = 10 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
calling PenDown() : rep = 9 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
calling PenDown() : rep = 8 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
calling PenDown() : rep = 7 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
calling PenDown() : rep = 6 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
calling PenDown() : rep = 5 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
calling PenDown() : rep = 4 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
calling PenDown() : rep = 3 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
calling PenDown() : rep = 2 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
calling PenDown() : rep = 1 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
calling PenDown() : rep = 0 , ret = 0

GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: PenDown()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
/home/preetam/Desktop/gmock/cpp_mock_ptr/test/mock_turtle_test.cc:20: Failure
Value of: painter.DrawCircle(0, 0, 10)
Actual: false
Expected: true
[ FAILED ] PainterTest.CanDrawSomething (0 ms)
[----------] 1 test from PainterTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (1 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] PainterTest.CanDrawSomething

1 FAILED TEST

最佳答案

你能创建一个 FakeTurtle 类型的模拟对象吗?并使用依赖注入(inject)技术(如果 Painter 需要成为注入(inject)对象的所有者,请参阅 Dependency injection with unique_ptr to mock;但首先尝试以 Painter 接受对 Turtle 的引用的方式重构您的代码,即在其构造函数中使用 Turtle& - 这更容易)。

GoogleMock 框架要求创建一个模拟对象,并且所有期望都设置在这个对象上(而不是其他一些对象)。

旁注:我会制作 Turtle纯虚拟界面。

关于c++ - 在 gmock 中使用指向带有 EXPECT_CALL 的模拟对象的指针会导致段错误或默认处理程序启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62316465/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com