Przykład: Chcemy przetestować metodę Filter::run(). Klasa do działania potrzebuje obiektów Inc i Show. Nie mają one czysto abstrakcyjnych interfejsów (ale zrobimy dla nich mocki). Show potrzebuje do działania referencji do Inc.
Problem pojawia się, gdy mock zrobimy StrictMock-iem i będziemy chcieli go jeszcze zainicjować. Tutaj ShowMock chcemy zainicjować IncMock (linijka 49-50).
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/ref.hpp>
#include <gmock/gmock.h>
using namespace std;
using namespace ::testing;
class Inc {
public:
virtual int inc(int v) { return v++; }
};
class IncMock : public Inc {
public:
MOCK_METHOD1(inc, int(int));
};
class Show {
Inc& obj;
public:
Show(Inc& i) : obj(i) {}
virtual void show(int v) { cout << "Val: " << obj.inc(v) << endl; }
};
class ShowMock : public Show {
public:
ShowMock(Inc& i) : Show(i) {}
MOCK_METHOD1(show, void(int));
};
class Filter {
boost::shared_ptr<Show> sw;
boost::shared_ptr<Inc> in;
public:
Filter(boost::shared_ptr<Show> s,
boost::shared_ptr<Inc> i) : sw(s), in(i) {}
void run(int val) {
if (val > 5)
sw->show(val);
in->inc(val);
}
};
TEST(FilterTest, test) {
boost::shared_ptr<IncMock> l_incMock(new StrictMock<IncMock>());
// NOT WORKING
// boost::shared_ptr<ShowMock> l_showMock(new StrictMock<ShowMock>
// (*l_incMock));
// NOT WORKING
// boost::shared_ptr<ShowMock> l_showMock(new StrictMock<ShowMock>
// (boost::cref(*l_incMock)));
boost::shared_ptr<ShowMock> l_showMock(new StrictMock<ShowMock>
(boost::ref(*l_incMock)));
Filter l_filter(l_showMock, l_incMock);
int l_val = 8;
EXPECT_CALL(*l_incMock, inc(l_val)).WillOnce(Return(l_val + 1));
EXPECT_CALL(*l_showMock, show(l_val));
l_filter.run(l_val);
}
int main(int argc, char *argv[]) {
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
Pierwsze rozwiązanie wypluje error przy kompilacjiIn file included from /home/niegodziwy/Downloads/gmock-1.6.0/include/gmock/gmock.h:64:0,
from main.cpp:4:
/home/niegodziwy/Downloads/gmock-1.6.0/include/gmock/gmock-generated-nice-strict.h: In constructor ‘testing::StrictMock<M>::StrictMock(const A1&) [with A1 = IncMock, MockClass = ShowMock]’:
main.cpp:48:77: instantiated from here
/home/niegodziwy/Downloads/gmock-1.6.0/include/gmock/gmock-generated-nice-strict.h:174:51: error: no matching function for call to ‘ShowMock::ShowMock(const IncMock&)’
/home/niegodziwy/Downloads/gmock-1.6.0/include/gmock/gmock-generated-nice-strict.h:174:51: note: candidates are:
main.cpp:28:5: note: ShowMock::ShowMock(Inc&)
main.cpp:28:5: note: no known conversion for argument 1 from ‘const IncMock’ to ‘Inc&’
main.cpp:26:7: note: ShowMock::ShowMock(const ShowMock&)
main.cpp:26:7: note: no known conversion for argument 1 from ‘const IncMock’ to ‘const ShowMock&’
Co się okazuje, StrictMock ma tylko konstruktory explicit, dlatego podziała trick z boost::ref().template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
Niestety nie wiem dlaczego nie działa boost::cref() ?!
Brak komentarzy:
Prześlij komentarz