Mockowanie setterów i getterów

0

Hej, korzystam z biblioteki gmock i zastanawiam się czy da się przetestować działanie settera nie wywołując jego kodu w teście? Czy mockowane metody nie robią zupełnie nic? Zamieszczam prosty program, który ilustruje moją nieudaną próbę.

vector.h

#ifndef VECTOR_H_
#define VECTOR_H_

class Vector
{
	private:
		double x;
		double y;
	public:
		virtual void setX(double a) {x = a;}
		virtual void setY(double b) {y = b;}
		virtual double getX() const {return x;}
		virtual double getY() const {return y;}
		virtual ~Vector() {}
};

#endif

vectorMock.h

#ifndef INCLUDE_VECTORMOCK_H_
#define INCLUDE_VECTORMOCK_H_

#include "gmock/gmock.h"
#include "vector.h"

class VectorMock : public Vector
{
	public:
		MOCK_METHOD1(setX, void(double a));
		MOCK_METHOD1(setY, void(double b));
		MOCK_CONST_METHOD0(getX, double());
		MOCK_CONST_METHOD0(getY, double());
};

#endif

testVector.cpp

#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "vector.h"
#include "vectorMock.h"
#include <iostream>

TEST(SetterAndGetterTest, test1)
{
	VectorMock m_VectorMock;
	m_VectorMock.setX(10);
	m_VectorMock.setY(20);
	EXPECT_EQ(10,m_VectorMock.getX());
	EXPECT_EQ(20,m_VectorMock.getY());
}
1

Parę spraw:

  • Nie ma sensu testować getterów itp. jeśli jedyne co robią to return;

*Po co są mocki, wyobraź sobie taką sytuację(bardzo skrótowo taki pseudo kod);


class A
{
  virtual int run() = 0;
};

class Aimp : public A{ // implementacja }

class B
{
  A* ob;
 B(A* obs) : ob(obs) {}
  int click() {
   int x = ob->run();
   ......
   return cos_tam;
}
};
 class MockA: public A { // mockowanie };
Test klasy B:
class BFixture : dziedziczenie po googlu
{ 
   B * test_ob;
   MockA* mockA; // też powinien zostać zinicjalizowany
   setup() { test_ob = new B(mockA); }
}
 Sam test:
Expect_Call(*mockA, run()).WillOnce(Return(0)); // Jeśli kalsa B wywoła mockA i wywoła metodę run to on raz zwróci 0 
Expect_EQ(0,B->click());

Podsumowując mock to symulowanie klasy gdy inna jej potrzebuje. W tym przypadku klasa B używa wewnętrznie klasy A ale przecież my testujemy klasę B nie A i nas nie obchodzi jej kod, to symulujemy. Więcej. https://github.com/google/googletest/blob/master/googlemock/docs/ForDummies.md

0

Rozumiem. A co w sytuacji, gdy testuje klasę B, która używa settera klasy A w testach. Nastepnie w tescie mam weryfikację tego czy setter zadziałał odpowiednio. Moje zadania polega na użyciu mocka klasy A w testach, zamiast rzeczywistego obiektu. Czy jedyne rozwiązanie polega na nie mockowaniu setter i wywołaniu go na rzecz mocka?

0

Nastepnie w tescie mam weryfikację tego czy setter zadziałał odpowiednio

To tym zajmuje się test UT klasy A. W teście klasy B możesz mieć EXPECT_CALL(*mockA, set()); czyli oczekujesz że klasa B zawoła setter klasy A z jakąś tam wartością.

0

Niestety jestem w nieco gorszej sytuacji. Otóż setter klasy A ustawia między innymi zmienną globalną. Jest on wywoływany na samym początku w teście klasy B. Następnie wywoływane są funkcje klasy B, których zachowanie jest zależne od stanu tej zmiennej globalnej. Na końcu mam weryfikacje, tego czy funkcje klasy B zadziałały poprawnie. Weryfikacja nie przechodzi, bo zmienna globalna nie miała odpowiedniego stanu.

0
kronos998 napisał(a):

Niestety jestem w nieco gorszej sytuacji. Otóż setter klasy A ustawia między innymi zmienną globalną. Jest on wywoływany na samym początku w teście klasy B. Następnie wywoływane są funkcje klasy B, których zachowanie jest zależne od stanu tej zmiennej globalnej. Na końcu mam weryfikacje, tego czy funkcje klasy B zadziałały poprawnie. Weryfikacja nie przechodzi, bo zmienna globalna nie miała odpowiedniego stanu.

To już użycie zmiennej globalnej wskazuje na jakiś problem w designie. Po co ci ta zmienna?

0

No cóż, nie ja jestem autorem tego rozwiązania, zastałem je w legacy. Moje zadanie polega jedynie na zastosowaniu mocka klasy A w testach klasy B.

1

Jak to UT to ustawiaj ręcznie tą globalną zmienną w teście i tyle. Poczytaj o invoke.
Do testu klasy A i B jednocześnie to są testy wyższych rzędów a nie UT.
edit:
A złe rozwiązanie może warto zmienić ? ;)

0

Wygląda to bardziej na testy integracyjne.

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