2016-04-06 25 views
0

Als ich Gmock von Google recherchierte, habe ich die Projektarbeit bisher gut installiert und aufgebaut. Aber ich habe Bedenken, eine Funktion zu verspotten. Jetzt habe ich die folgenden Dateien:Re-Routing einer realen Funktion zu einer Spottfunktion mit Gmock?

< 1> myGtest.h

#ifndef MYGTEST_H_ 
#define MYGTEST_H_ 

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

#endif /* MYGTEST_H_ */ 

< 2> 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; 
} 

< 3> myGtest_dummy.h

#ifndef MYGTEST_DUMMY_H_ 
#define MYGTEST_DUMMY_H_ 

#include "gmock/gmock.h" 
#include "../myGtest/myGtest.h" 

class myGtestMock 
{ 
public: 
    myGtestMock(){}; 
    ~myGtestMock(){}; 
    MOCK_METHOD1(test, int(int)); 
}; 

#endif /* MYGTEST_DUMMY_H_ */ 

< 4> 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(); 
} 

Können Sie mir helfen, das zu erklären: Wie kann ich die Funktion int test(int) verspotten? Ich würde gerne erwarten, dass, sobald TEST_F(BTest, CallMockTest) ausgeführt wird, der Programmaufruf function(99);. Dann wird meine Spottfunktion statt int test(int) aufgerufen.

Vielen Dank für die Antwort.

Antwort

0

Die Schlüsselidee hier ist zu realisieren, dass Mocks Objekte sind das Verhalten von realen Objekten verspotten. Das bedeutet, dass Sie Erwartungen an sie setzen (dh: wie oft sie aufgerufen werden, mit welchen Argumenten usw.) und Sie einige Aktionen mit den Mocks simulieren (dh: bestimmte Werte zurückgeben oder einige Parameter ändern usw.)

Mit Ihrer aktuellen Implementierung wird beim Aufruf von function() immer noch die eigentliche Implementierung von test() aufgerufen. So wird Ihr EXPECT_CALL immer fehlschlagen. Idealerweise sollte test() Teil einer Schnittstelle sein, die Sie nachahmen möchten. Sprich:

class MyInterface{ 
public: 
    ... 
    virtual int test(int a) = 0;  
}; 

Hinweis: Der Einfachheit halber ich die reale Umsetzung der MyInterface außer Acht lassen wird, sowieso, da wir die wirkliche Implementierung mit unserer mock vorbeigehen beabsichtigen.

Jetzt sollte Funktion(), die die Funktion im Test ist, idealerweise Teil der Klasse sein. Ändern Sie Ihre Implementierung ein wenig:

class MyClass{ 
    .... 
    int function(int a, MyInterface * interface){ 
     int x = interface->test(a); 
     if(x == 0) 
      return 99; 
     else 
      return 0; 
    } 
}; 

Jetzt, mit dem zweiten Parameter von function(), können Sie den erstellten Schein übergeben. Aber vorher müssen Sie festlegen, dass Sie MyInterface spotten:

class myGtestMock : public MyInterface{ 
    .... 
}; 

nun in Ihre Testdatei:

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 
} 

Es gibt viele Tricks, die Sie von Google CookBook verspotten lernen können

+0

Dank so viel für deine Zeit, um mir zu antworten. –

+0

Ich habe verstanden, was Sie gesagt haben. Aber, mein Kunde gab mir nur den Quellcode ('src_code.c') und ich darf es nicht editieren. Angenommen, ich teste 'function()' und in 'function()' wird der 'test()' aufgerufen. Das Problem hier, "test", ist sehr, sehr komplex, also möchte ich es als einen Stub machen, und nur den _return value_ und den Wert des _output args_ dieses Stubs kontrollieren wollen. –

+0

Siehe diesen Link: http: // stackoverflow.com/questions/19552805/using-google-mock-for-c-code – MIbrah