mirror of
https://github.com/google/googletest.git
synced 2025-12-08 01:36:50 +08:00
148 lines
4.0 KiB
C++
148 lines
4.0 KiB
C++
#include <string>
|
|
|
|
#include "cotest/cotest.h"
|
|
#include "gtest/gtest-spi.h"
|
|
|
|
using namespace std;
|
|
using namespace testing;
|
|
using ::testing::StrictMock;
|
|
|
|
////////////////////////////////////////////
|
|
// Code under test
|
|
|
|
class ClassToMock {
|
|
public:
|
|
virtual ~ClassToMock() {}
|
|
virtual int Mock1(int i) = 0;
|
|
virtual int Mock2(int i, int j) const = 0;
|
|
virtual int Mock3(int i) const = 0;
|
|
virtual int Mock4(int i) const = 0;
|
|
virtual int Mock4(int i) = 0;
|
|
};
|
|
|
|
class ExampleClass {
|
|
public:
|
|
ExampleClass(ClassToMock *dep_) : dep(dep_) {}
|
|
|
|
int Example1(int a) { return dep->Mock1(a + 1) * 2; }
|
|
|
|
int Example2(int a) { return dep->Mock1(a + 1) * dep->Mock1(0); }
|
|
|
|
private:
|
|
ClassToMock *const dep;
|
|
};
|
|
|
|
//////////////////////////////////////////////
|
|
// Mocking assets
|
|
|
|
class MockClass : public ClassToMock {
|
|
public:
|
|
MOCK_METHOD(int, Mock1, (int i), (override));
|
|
MOCK_METHOD(int, Mock2, (int i, int j), (const, override));
|
|
MOCK_METHOD(int, Mock3, (int i), (const, override));
|
|
MOCK_METHOD(int, Mock4, (int i), (const, override));
|
|
MOCK_METHOD(int, Mock4, (int i), (override));
|
|
};
|
|
|
|
//////////////////////////////////////////////
|
|
// The actual tests
|
|
|
|
StrictMock<MockClass> *mock_object_p = nullptr;
|
|
|
|
/*
|
|
* Why this works
|
|
*
|
|
* Expectations, watches etc are created in the coro but under shared_ptr<>
|
|
* and are held alive by the mockers in the mock object. In this test case,
|
|
* the mockers outlast the coro itself, so we end up using DetachCoroutine()
|
|
* etc.
|
|
*/
|
|
TEST(AllInTest, WatchInside) {
|
|
StrictMock<MockClass> mock_object;
|
|
StrictMock<MockClass> mock_object2;
|
|
|
|
auto coro = COROUTINE() {
|
|
WATCH_CALL(mock_object, Mock1);
|
|
WATCH_CALL(mock_object, Mock2);
|
|
|
|
// See later tests in which LAUNCH() is used to run code-under-test
|
|
// from within coroutine.
|
|
mock_object_p = &mock_object;
|
|
|
|
auto cg = WAIT_FOR_CALL();
|
|
EXPECT_FALSE(cg.IS_CALL(mock_object, Mock1(201)));
|
|
EXPECT_FALSE(cg.IS_CALL(mock_object2, Mock1));
|
|
EXPECT_FALSE(cg.IS_CALL(mock_object2, Mock1(_)));
|
|
EXPECT_FALSE(cg.IS_CALL(mock_object2, Mock1(200)));
|
|
EXPECT_TRUE(cg.IS_CALL(mock_object, Mock1));
|
|
EXPECT_TRUE(cg.IS_CALL(mock_object, Mock1(_)));
|
|
EXPECT_TRUE(cg.IS_CALL(mock_object, Mock1(200)).RETURN(20));
|
|
cg = WAIT_FOR_CALL();
|
|
EXPECT_FALSE(cg.IS_CALL(mock_object, Mock2(_, 401)));
|
|
EXPECT_TRUE(cg.IS_CALL(mock_object, Mock2));
|
|
EXPECT_TRUE(cg.IS_CALL(mock_object, Mock2(_, _)));
|
|
EXPECT_TRUE(cg.IS_CALL(mock_object, Mock2(_, 400)));
|
|
EXPECT_TRUE(cg.IS_CALL(mock_object, Mock2(200, _)).RETURN(30));
|
|
};
|
|
|
|
ASSERT_TRUE(mock_object_p);
|
|
|
|
EXPECT_EQ(mock_object_p->Mock1(200), 20);
|
|
EXPECT_EQ(mock_object_p->Mock2(200, 400), 30);
|
|
|
|
mock_object_p = nullptr;
|
|
}
|
|
|
|
TEST(AllInTest, LaunchMock) {
|
|
auto coro = COROUTINE() {
|
|
StrictMock<MockClass> mock_object;
|
|
ExampleClass example(&mock_object);
|
|
|
|
WATCH_CALL();
|
|
|
|
auto d = LAUNCH(example.Example1(4));
|
|
|
|
auto e = NEXT_EVENT();
|
|
EXPECT_TRUE(e.IS_CALL(mock_object, Mock1(5)).RETURN(1000));
|
|
|
|
e = NEXT_EVENT();
|
|
EXPECT_TRUE(e.IS_RESULT(d));
|
|
EXPECT_EQ(e(d), 2000);
|
|
};
|
|
}
|
|
|
|
COTEST(AllInTest, CotestMacro) {
|
|
StrictMock<MockClass> mock_object;
|
|
ExampleClass example(&mock_object);
|
|
|
|
WATCH_CALL();
|
|
|
|
auto d = LAUNCH(example.Example1(4));
|
|
|
|
auto cs = WAIT_FOR_CALL(mock_object, Mock1);
|
|
EXPECT_TRUE(cs.GetArg<0>() == 5);
|
|
cs.RETURN(1000);
|
|
|
|
auto e = WAIT_FOR_RESULT();
|
|
EXPECT_EQ(e(d), 2000);
|
|
}
|
|
|
|
COTEST(AllInTest, CotestMacroWithExpect) {
|
|
StrictMock<MockClass> mock_object;
|
|
ExampleClass example(&mock_object);
|
|
|
|
// EXPECT_CALL() is fine inside a COTEST(). Semantics are the
|
|
// same.
|
|
EXPECT_CALL(mock_object, Mock1(0)).WillRepeatedly(Return(1));
|
|
WATCH_CALL();
|
|
|
|
auto d = LAUNCH(example.Example2(4));
|
|
|
|
auto cs = WAIT_FOR_CALL(mock_object, Mock1(Gt(0)));
|
|
EXPECT_TRUE(cs.GetArg<0>() == 5);
|
|
cs.RETURN(1000);
|
|
|
|
auto e = WAIT_FOR_RESULT();
|
|
EXPECT_EQ(e(d), 1000);
|
|
}
|