Mocking will einfach nicht



  • Ich arbeite mich gerade in Unit Testing ein und habe mich vorerst auf google test festgelegt.

    Nachdem ich Probleme mit vielen Dependencies im Code hatte habe ich den Hinweis bekommen mir mal Mocking anzusehen. Zum Glück gibts da auch was von google ;). Nachdem ich eine Mockingklasse und den entsprechenden Test sowie ein Makefile gebaut und einige Compilerfehler wegbekommen habe weiß ich nun allerdings nicht weiter. Was mich aktuell hindert den Test ausführen zu können sind einige "undefined dependencies" die ich einfach nicht auflösen kann.
    Ich poste hier mein Problem mal in vereinfachter Form

    Die zu testende Klasse:
    ZuTesten.h

    #ifndef _ZuTesten_
    #define _ZuTesten_
    
    #include <2Bib/ZuSim.h>
    
    class KZuTesten 
    {
    
       public:
       KZuTesten();
    
       void OnExecution(void);
       private:
    };
    

    ZuTesten.cpp

    #include <ZuTesten.h>
    
    extern KZuSim Sim;
    
    KZuTesten::KZuTesten()
    {
    }
    
    void KZuTesten::OnExecution(void)
    {
       ZuSim.Foo();
    }
    

    Die zu mockende Klasse:
    ZuSim.h

    #ifndef _ZuSim_
    #define _ZuSim_
    
    #include <Config.h>
    #include <Object.h>
    
    #include <Port.h>
    
    #include <Volt.h>
    #include <Core.h>
    #define ZuSim_CLASSNAME "ZuSim"
    
    class KZuSim : public Object, public Hand
    {
    
       public:
          KZuSim(ExtInt* extInt);
    
          void Foo(void);
    
          void Rest1(void);
    
          void Rest2(void);
    
          bool GPress(void);
    
          bool F2F(void);
    
          virtual void Call0(void);
    
    };
    

    ZuSim.cpp

    #include <ZuSim.h>
    
    KZuSim::KZuSim(ExtInt* extInt)
    {
       int Snafu = 0;   
    }
    
    bool KZuSim::Init(void)
    {
       ...
    }
    
    void KZuSim::Call0(void)
    {
       ...
    }
    
    void KZuSim::Foo(void)
    {
       int bar;
    }
    
    void KZuSim::Rest(void)
    {
       ...
    }
    

    MockKlasse:
    MockZuSim.h

    #ifndef _MOCKZUSIM_
    #define _MOCKZUSIM_
    
    #include <gtest/gtest.h>
    #include <gmock/gmock.h>
    #include <2Bib/ZuSim.h>
    
    class MockKZuSim : public KZuSim
    
    {
       public:
    MockKZuSim();
    
    int KZuSim();
    MOCK_METHOD0(Foo,void());
    };
    
    #endif
    

    Der Test
    ZuTest_mocktest

    #include "ZuTesten.h"
    #include <gtest/gtest.h>
    #include <gmock/gmock.h>
    #include "MockKZuSim.h"
    using ::testing::AtLeast;
    
    TEST(ZuTesten_mocktest, Foo)
    {
    	MockKZuSim MZuSim;
    	EXPECT_CALL(MZuSim, Foo()).Times(AtLeast(1));
    
    	KZuTesten K;
    	K.OnExecution();
    	//(&KFoot);
    	//EXPECT_TRUE(K.OnExecution);
    }
    

    Dafür habe ich mir dann ein Makefile gebaut

    GTEST_DIR = ../../test
    
    GMOCK_DIR = ..
    
    USER_DIR = ../../3/Task
    
    SUB_DIR = ../../
    
    # Flags passed to the preprocessor.
    CPPFLAGS += -I$(GTEST_DIR)/include -I$(GMOCK_DIR)/include
    CPPFLAGS += -I ../../
    
    # Flags passed to the C++ compiler.
    CXXFLAGS += -g -Wall -Wextra
    
    # All tests produced by this Makefile.  Remember to add new tests you
    # created to the list.
    TESTS = ZuTesten_mocktest
    
    # All Google Test headers.  Usually you shouldn't change this
    # definition.
    GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
                    $(GTEST_DIR)/include/gtest/internal/*.h
    
    # All Google Mock headers. Note that all Google Test headers are
    # included here too, as they are #included by Google Mock headers.
    # Usually you shouldn't change this definition.	
    GMOCK_HEADERS = $(GMOCK_DIR)/include/gmock/*.h \
                    $(GMOCK_DIR)/include/gmock/internal/*.h \
                    $(GTEST_HEADERS)
    
    # House-keeping build targets.
    
    all : $(TESTS)
    
    clean :
    	rm -f $(TESTS) gmock.a gmock_main.a *.o
    
    # Builds gmock.a and gmock_main.a.  These libraries contain both
    # Google Mock and Google Test.  A test should link with either gmock.a
    # or gmock_main.a, depending on whether it defines its own main()
    # function.  It's fine if your test only uses features from Google
    # Test (and not Google Mock).
    
    # Usually you shouldn't tweak such internal variables, indicated by a
    # trailing _.
    GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
    GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS)
    
    # For simplicity and to avoid depending on implementation details of
    # Google Mock and Google Test, the dependencies specified below are
    # conservative and not optimized.  This is fine as Google Mock and
    # Google Test compile fast and for ordinary users their source rarely
    # changes.
    gtest-all.o : $(GTEST_SRCS_)
    	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest-all.cc
    
    gmock-all.o : $(GMOCK_SRCS_)
    	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) -c $(GMOCK_DIR)/src/gmock-all.cc
    
    gmock_main.o : $(GMOCK_SRCS_)
    	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) -c $(GMOCK_DIR)/src/gmock_main.cc
    
    gmock.a : gmock-all.o gtest-all.o
    	$(AR) $(ARFLAGS) $@ $^
    
    gmock_main.a : gmock-all.o gtest-all.o gmock_main.o
    	$(AR) $(ARFLAGS) $@ $^
    
    ZuTesten.o : $(USER_DIR)/ZuTesten.cpp $(USER_DIR)/ZuTesten.h $(GTEST_HEADERS)
    	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ZuTesten.cpp
    
    ZuTesten_mocktest.o : $(USER_DIR)/ZuTesten_mocktest.cpp $(GTEST_HEADERS)
    	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ZuTesten_mocktest.cpp 
    
    ZuTesten_mocktest : ZuTesten.o ZuTesten_mocktest.o gmock_main.a
    	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
    

    Ach ja und die Fehlermeldungen sehen dann so aus:

    ZuTesten.o: In function KZutesten::OnExecution()': /home/me/code/gtest/mocks/make/../../3/Task/ZuTesten.cpp:49: undefined reference toZuSim'

    /home/me/code/gtest/mocks/make/../../3/Task/ZuTesten.cpp:49: undefined reference to `KZuSim::Foo()'

    Zutesten_mocktest.o: In function 'ZuTesten_mocktest_Foo_Test::TestBody()':

    /home/me/code/gtest/mocks/make/../../3/Task/ZuTesten_mocktest.cpp:9: undefined reference to `MockKZuSim::MockKZuSim()'

    ZuTesten_mocktest.o:(.rodata._ZTV9MockKZuSim[vtable for MockKZuSim]+0x10): undefined reference to `KZuSim::Init()'

    ZuTesten_mocktest.o:(.rodata._ZTV9MockKZuSim[vtable for MockKZuSim]+0x14): undefined reference to `KZuSim::Call0()'

    ZuTesten_mocktest.o:(.rodata._ZTV9MockKFoot[vtable for MockKFoot]+0x44): undefined reference to `Hand::GetWarning()'

    PollFootTask_mocktest.o:(.rodata._ZTV9MockKFoot[vtable for MockKFoot]+0x5c): undefined reference to `non-virtual thunk to KZuSim::Call0()'

    Entschuldigt den ellenlangen Beitrag aber ich weiß mir gerade nicht mehr zu helfen und finde auch kein gutes Beispiel an dem ich mich langhangeln könnte.

    Achso noch kurz zum Grundproblem. Eigentlich geht es darum das der Code sehr hardwarenah ist und ich ihn deshlab auf dem Testrechner nicht übersetzen kann. Um nun die Klasse zuTesten zu testen möchte ich die ZuSim eben simulieren um aus den ganzen Abhängigkeiten heraus zu kommen.


Anmelden zum Antworten