Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.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
C++ 使用Gmock将实函数重新路由到模拟函数?_C++_Unit Testing_Testing_Googletest_Gmock - Fatal编程技术网

C++ 使用Gmock将实函数重新路由到模拟函数?

C++ 使用Gmock将实函数重新路由到模拟函数?,c++,unit-testing,testing,googletest,gmock,C++,Unit Testing,Testing,Googletest,Gmock,当我从谷歌研究Gmock时,我已经安装并构建了该项目,到目前为止效果良好。但我对模拟函数有些担心。现在我有以下文件: myGtest.h #ifndef MYGTEST_H_ #define MYGTEST_H_ int test(int); int function(int); #endif /* MYGTEST_H_ */ src_code.cpp #include <stdio.h> #include "myGtest.h" int test(int a) {

当我从谷歌研究Gmock时,我已经安装并构建了该项目,到目前为止效果良好。但我对模拟函数有些担心。现在我有以下文件:

myGtest.h

#ifndef MYGTEST_H_
#define MYGTEST_H_

int test(int);
int function(int);

#endif /* MYGTEST_H_ */
src_code.cpp

#include <stdio.h>
#include "myGtest.h"

int test(int a) {
    printf("NOT overridden!\n");
    return a;
}

int function(int a){

    int x = test(a);
    if(x == 0)
        return 99;
    else
        return 0;
}
test_program.cpp

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "src/myGtest/myGtest.h"
#include "src/dummy/myGtest_dummy.h"

using testing::_;
using testing::Return;
using testing::InSequence;
using ::testing::AtLeast;

extern int function(int a);
extern int test(int a);

class BTest:public testing::Test{
public:
    myGtestMock mock_test;


    int __wrap_test(int a);
};

int BTest::__wrap_test(int a){

    printf("overridden!\n");
    return a;
}

TEST_F(BTest, CallMockTest) {

    EXPECT_CALL(mock_test, test(0))
            .WillOnce(Invoke(this, &BTest::__wrap_test));

    function(99);
}

int main(int argc, char *argv[]) {

    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
#包括
#包括
#包括“src/myGtest/myGtest.h”
#包括“src/dummy/myGtest_dummy.h”
使用测试::;
使用测试::返回;
使用测试::不连续;
使用::testing::至少;
外部内部函数(INTA);
外部内部测试(INTA);
B类测试:公共测试::测试{
公众:
myGtestMock_试验;
int包装试验(INTA);
};
int BTest::uuu包装_u测试(int a){
printf(“覆盖!\n”);
返回a;
}
测试(B测试、CallMockTest){
EXPECT_调用(模拟_测试,测试(0))
.WillOnce(调用(this,&BTest::\uuu wrap\u test));
功能(99);
}
int main(int argc,char*argv[]){
::测试::InitGoogleTest(&argc,argv);
返回运行所有测试();
}
你能帮我解释一下:我如何模拟函数
inttest(int)
?我希望在执行
TEST\F(BTest,CallMockTest)
后,程序调用
函数(99)。然后将调用我的模拟函数
int\uu wrap\u test(int)
,而不是
int test(int)


非常感谢您的回答。

这里的关键思想是要认识到,模拟是对象模拟真实对象的行为。这意味着您对它们设置了期望值(即:调用它们的次数、使用哪些参数等),并使用模拟来模拟某些操作(即:返回特定值或更改某些参数等)

在当前实现中,调用function()时,它仍将调用test()的实际实现。所以你的预期呼叫总是会失败。理想情况下,test()应该是要模拟的接口的一部分。说:

class MyInterface{
public:
    ...
    virtual int test(int a) = 0;    
};
注意:为了简单起见,我将忽略MyInterface的实际实现,因为无论如何,我们打算使用我们的mock绕过真正的实现

现在,被测试的函数function()理想情况下应该是类的一部分。稍微更改一下您的实现:

class MyClass{
    ....
    int function(int a, MyInterface * interface){
        int x = interface->test(a);
        if(x == 0)
            return 99;
        else
            return 0;   
    }
};
现在,使用function()的第二个参数,可以传递创建的模拟。但在此之前,您需要定义您正在模拟MyInterface:

class myGtestMock : public MyInterface{
    ....
};
现在,在您的测试文件中:

TEST_F(BTest, CallMockTest) {
    myGtestMock myMockObj;

    //Testing (x==0)
    EXPECT_CALL(myMockObj, test(99))   
    .Times(1)
    .WillOnce(Return(0));       //set the action

    EXPECT_EQ(99,function(99, &myMockObj));
    Mock::VerifyAndClear(&myMockObj); //to clear the expectation

    //testing else
    EXPECT_CALL(myMockObj, test(99))   
    .Times(1)
    .WillOnce(Return(1));       //set the action

    EXPECT_EQ(0,function(99, &myMockObj));
    Mock::VerifyAndClear(&myMockObj); //to clear the expectation
}  

你可以从google mock中学到很多技巧

非常感谢你抽出时间回答我。我理解你所说的。但是,我的客户只给了我源代码(
src_code.c
),我不能编辑它。假设我正在测试
function()
,并在
function()
中调用
test()
。这里的问题,
test
非常复杂,所以我想将其作为存根,只想控制存根的返回值和输出参数的值。请参阅此链接:我不能说我理解这里提到的所有内容,但我认为这与您要查找的内容一致。谢谢。我以前研究过这个弱属性。但是,不幸的是,它只创建了一个从实函数到弱函数的链接,一旦我调用实函数,编译器总是将它重新路由到弱函数,我不能再使用实函数了。如此悲伤!
TEST_F(BTest, CallMockTest) {
    myGtestMock myMockObj;

    //Testing (x==0)
    EXPECT_CALL(myMockObj, test(99))   
    .Times(1)
    .WillOnce(Return(0));       //set the action

    EXPECT_EQ(99,function(99, &myMockObj));
    Mock::VerifyAndClear(&myMockObj); //to clear the expectation

    //testing else
    EXPECT_CALL(myMockObj, test(99))   
    .Times(1)
    .WillOnce(Return(1));       //set the action

    EXPECT_EQ(0,function(99, &myMockObj));
    Mock::VerifyAndClear(&myMockObj); //to clear the expectation
}