Mockowanie metod klasy pochodnej

0

Cześć,
W programie mam następującą hierarchię klas:

class A 
{
  ...
  virtual void fun() = 0;
  ...
}

class B : public class A
{
  ...
  virtual void fun() {std::cout << "Metoda klasy B \n";}
  ...
}

class MockA : public A
{
  ...
  MOCK_METHOD0(fun());
  ...
}

W testach innej klasy chcę zamockować wywołanie funkcji fun():

   ...
   A *ptr = new B();
   ptr->fun(); // wywołanie oryginalnej funkcji B::fun() zamiast mocka

Pytania:

  1. Dlaczego następuję wywołanie metody z klasy B a nie mocka?
  2. W jaki sposób to naprawić?
0

Tworzysz instancję B i wywołuje się metoda w B. Co tu chcesz "naprawiać"?

1

Używasz gtest?
MOCK_METHOD0(fun()); wydaje się że to powinno wyglądać tak -> MOCK_METHOD0(fun, void());
Dlaczego następuję wywołanie metody z klasy B a nie mocka? bo tworzysz obiekt klasy B, a nie klasy MockA.
Ja bym to zmienił na:

class MockB : public B
{
  ...
  MOCK_METHOD0(fun, void());
  ...
}
...
A *ptr = new MockB();
2

Za mało kontekstu!
Po pierwsze gdzie jest klasa podlegająca testowaniu? Gdzie jest twój test?
Po drugie jak testowana klasa używa zależności?
Po trzecie tak jak wspomniał @nullpt4 twój kod nie jest prawidłową definicją mocka w gtest.

Pytanie jest tak rozmyte, że trzeba było by tłumaczyć dokumentację gtest i gmock (która jest jasna czytelna i kompletna), na język polski.

https://github.com/google/googletest/blob/master/googlemock/docs/CheatSheet.md

Moje testy wyglądają zwykle w ten sposób (uwaga literówki):

// MockB.h
#include <B.h>
#include <gmock/gmock.h>

class MockB : public B
{
public:
  MOCK_METHOD1(fun, void(int x)); // zmieniłem prototyp funkcji fun by było ciekawiej
};
// testC.cpp
#include "set_nod.h"

#include"MockB.h"
#include"Foo.h"

#include <gtest/gtest.h>

using testing::Ge;

class FooTest : public testing::Test
{
public:
    void SetUp() override {
        mMock = std::make_unique<MockB>();
        mUnderTest = std::make_unique<Foo>();
        mUnderTest->setB(mMock.get());
    }

public:
    std::unique_ptr<MockB> mMock;
    std::unique_ptr<Foo> mUnderTest;
};

TEST_F(FooTest, WhenDoingX_ItCallsBFunWithXGreaterThen3) // pilnuje by nazwa testu była BARDZO opisowa, trzymam się zasady Given, When_Then
{
    // większość moich testów mieści się w 5 linijkach
    EXPECT_CALL(*mMock, fun(Ge(3)));
    mUnderTest->doX();
}

Przy czym klasy mocków często dekoruję funkcjami pomocniczymi pomagającymi w opisowy sposób napisać kod z oczekiwaniami użycia mock-a.

1 użytkowników online, w tym zalogowanych: 0, gości: 1