## GMOCK

* <!-- .element: class="fragment fade-in" --> Avoid depricated <code>MOCK_METHDn</code> and <code>MOCK_CONST_METHODn</code>
* <!-- .element: class="fragment fade-in" --> Use <code>MOCK_METHOD()</code>
* <!-- .element: class="fragment fade-in" --> Use <code>Times</code> when want to expect how many times function was call (by default it expect once)
* <!-- .element: class="fragment fade-in" --> Use <code>AtLeast</code> To expect <b>n</b> or more calls
* <!-- .element: class="fragment fade-in" --> Use <code>WillOnce</code> and <code>WillRepeatedly</code> to perform some actions
* <!-- .element: class="fragment fade-in" --> Use <code>SaveArg</code> to save argument provided to mock function
* <!-- .element: class="fragment fade-in" --> Use <code>InSequence</code> to perform sequenced actions
* <!-- .element: class="fragment fade-in" --> You can mock non-virtual function
* <!-- .element: class="fragment fade-in" --> Use <code>StrictMock</code> when you need to be sure about every call of this mock
* <!-- .element: class="fragment fade-in" --> Use <code>NiceMock</code> when you don't care about function called for this mock
* <!-- .element: class="fragment fade-in" --> Use <code>ON_CALL</code> and <code>WillByDefault</code> to perform some default action, when function will be called
* <!-- .element: class="fragment fade-in" --> Use <code>DoAll</code> to perform more then one action
* <!-- .element: class="fragment fade-in" --> Use <code>Invoke</code> to invoke funtion/lambda

<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## MOCK_METHOD

MOCK_METHOD(return_type, name_of_function, arguments, parameters)
<!-- .element: class="fragment fade-in" -->

```C++
class MockTurtle : public Turtle {
 public:
  ...
  MOCK_METHOD(void, PenUp, (), (override));
  MOCK_METHOD(void, PenDown, (), (override));
  MOCK_METHOD(void, Forward, (int distance), (override));
  MOCK_METHOD(void, Turn, (int degrees), (override));
  MOCK_METHOD(void, GoTo, (int x, int y), (override));
  MOCK_METHOD(int, GetX, (), (const, override));
  MOCK_METHOD(int, GetY, (), (const, override));
};
```
<!-- .element: class="fragment fade-in" -->

* <!-- .element: class="fragment fade-in" --> const - Makes the mocked method a const method. Required if overriding a const method.
* <!-- .element: class="fragment fade-in" --> override - Marks the method with override. Recommended if overriding a virtual method.
* <!-- .element: class="fragment fade-in" --> noexcept - Marks the method with noexcept. Required if overriding a noexcept method.
* <!-- .element: class="fragment fade-in" --> Calltype(...) - Sets the call type for the method (e.g. to STDMETHODCALLTYPE), useful in Windows.
* <!-- .element: class="fragment fade-in" --> ref(...) - Marks the method with the reference qualification specified. Required if overriding a method that has reference qualifications. Eg ref(&) or ref(&&).
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## Test class

Let's use once agin `Foo` and `Bar` class

```C++
class Bar {
public:
    virtual ~Bar() = default;

    virtual bool doOtherStuff(const std::string& str, int*, const std::vector<int>& vec) const {
        // do some stuff
        return false;
    }
};

class MockBar : public Bar {
public:
    ~MockBar() override = default;
    MOCK_METHOD(bool, doOtherStuff, (const std::string&, int*, const std::vector<int>&), (const override));
};

class Foo {
public:
    Foo(std::unique_ptr<Bar> bar)
        : val_(std::make_unique<int>(42)),
          bar_(std::move(bar)) {}

    bool doSth(const std::string& str) {
        return bar_->doOtherStuff(str, val_.get(), {1, 2, 3, 4});
    }

private:
    std::unique_ptr<int> val_;
    std::unique_ptr<Bar> bar_;
};

```
<!-- .slide: style="font-size: 0.63em" -->
___
<!-- .slide: data-background="#ccc" -->
## Times

```C++
TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));

    EXPECT_CALL(*mockBarPtr, doOtherStuff).Times(2);

    foo.doSth("Sth1");
    foo.doSth("Sth2");
}
```

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## AtLeast

```C++
TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));

    EXPECT_CALL(*mockBarPtr, doOtherStuff).Times(testing::AtLeast(2));

    foo.doSth("Sth1");
    foo.doSth("Sth2");
}
```

<!-- .element: class="fragment fade-in" -->
___
<!-- .slide: data-background="#ccc" -->
## WillOnce and WillRepeatedly

```C++
TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));

    // Dont do that. Next exceptaion will override first one!
    // EXPECT_CALL(*mockBarPtr, doOtherStuff).WillOnce(Return(false));
    // EXPECT_CALL(*mockBarPtr, doOtherStuff).WillOnce(Return(true));

    // Correct one!
    EXPECT_CALL(*mockBarPtr, doOtherStuff)
        .WillOnce(Return(false))
        .WillOnce(Return(true));

    EXPECT_FALSE(foo.doSth("Sth1"));
    EXPECT_TRUE(foo.doSth("Sth2"));
}
```
<!-- .element: class="fragment fade-in" -->

```C++
TEST(ExampleTest, ShouldTest) {
    //...
    EXPECT_CALL(*mockBarPtr, doOtherStuff)
        .WillOnce(Return(false))
        .WillOnce(Return(true))
        .WillRepeatedly(Return(false));

    EXPECT_FALSE(foo.doSth("Sth1"));
    EXPECT_TRUE(foo.doSth("Sth2"));
    EXPECT_FALSE(foo.doSth("Sth3"));
    EXPECT_FALSE(foo.doSth("Sth4"));
}
```
<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.68em" -->

___

<!-- .slide: data-background="#ccc" -->
## Save arguments provided to functions (1)

We want to capture parameters provided to bar function.

```C++
class Bar {
public:
    virtual ~Bar() = default;

    virtual bool doOtherStuff(const std::string& str, int val, const std::vector<int>& vec) {
        // do some stuff
        return false;
    }
};

class MockBar : public Bar {
public:
    ~MockBar() override = default;
    MOCK_METHOD(bool, doOtherStuff, (const std::string&, int, const std::vector<int>&), (override));
};

class Foo {
public:
    Foo(std::unique_ptr<Bar> bar)
        : bar_(std::move(bar)) {}

    bool doSth(const std::string& str) {
        return bar_->doOtherStuff(str, 42, {1, 2, 3, 4});
    }

private:
    std::unique_ptr<Bar> bar_;
};
```
<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.65em" -->
___
<!-- .slide: data-background="#ccc" -->
## Save arguments provided to functions (2)

```C++
TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));

    int val;
    std::vector<int> vec;
    // Also return true, instead of false like in original function
    EXPECT_CALL(*mockBarPtr, doOtherStuff).
        WillOnce(DoAll(SaveArg<1>(&val), SaveArg<2>(&vec), Return(true)));

    EXPECT_TRUE(foo.doSth("Sth"));
    EXPECT_EQ(val, 42);
    const auto expected = std::vector<int>{1, 2, 3, 4};
    EXPECT_EQ(vec, expected);
}
```
<!-- .element: class="fragment fade-in" -->

```
[----------] 1 test from ExampleTest
[ RUN      ] ExampleTest.ShouldTest
[       OK ] ExampleTest.ShouldTest (0 ms)
[----------] 1 test from ExampleTest (0 ms total)
```
<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.78em" -->
___
<!-- .slide: data-background="#ccc" -->
## Save pointer provided to function

```C++
class Bar {
public:
    virtual ~Bar() = default;

    virtual bool doOtherStuff(const std::string& str, int* val, const std::vector<int>& vec) {
        // do some stuff
        return false;
    }
};

```
<!-- .element: class="fragment fade-in" -->

```C++
TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));

    int* val;
    std::vector<int> vec;
    // Capture by SaveArgPointee
    EXPECT_CALL(*mockBarPtr, doOtherStuff).
        WillOnce(DoAll(SaveArgPointee<1>(val), SaveArg<2>(&vec), Return(true)));

    EXPECT_TRUE(foo.doSth("Sth"));
    EXPECT_EQ(*val, 42);
    const auto expected = std::vector<int>{1, 2, 3, 4};
    EXPECT_EQ(vec, expected);
}
```
<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.7em" -->
___
<!-- .slide: data-background="#ccc" -->
## Capture non-copyable object

* <!-- .element: class="fragment fade-in" --> There is a problem to capture non-copyable objects because we can't copy them!
* <!-- .element: class="fragment fade-in" --> We need to make an ugly hack to capture this object -> move this object to our variable.
* <!-- .element: class="fragment fade-in" --> This will be problematic when this object needs to be used in a function, but it will work when we used in on mock function because the argument will not be used later.

```C++
// Bar
bool doSth(const std::string& str) {
    return bar_->doOtherStuff(str, std::make_unique<int>(42), {1, 2, 3, 4});
}

TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));

    std::unique_ptr<int> val;
    EXPECT_CALL(*mockBarPtr, doOtherStuff).WillOnce(DoAll(MoveObject<1>(&val), Return(true)));

    EXPECT_TRUE(foo.doSth("Sth"));
    EXPECT_EQ(*val, 42);
}
```
<!-- .element: class="fragment fade-in" -->

* <!-- .element: class="fragment fade-in" --> <b>There is no such function in gtest, so we need to implement somehow <code>MoveObject</code></b>
<!-- .slide: style="font-size: 0.7em" -->
___
<!-- .slide: data-background="#ccc" -->
## Move object

```C++
ACTION_TEMPLATE(MoveObject,
                HAS_1_TEMPLATE_PARAMS(int, k),
                AND_1_VALUE_PARAMS(pointer)) {
    using PtrType = std::remove_cv_t<std::remove_reference_t<decltype(std::get<k>(args))>>;
    // This unique_ptr will be deleted after function end
    // so we need to capture it
    *pointer = std::move(const_cast<PtrType&>(std::get<k>(args)));
}
```
<!-- .element: class="fragment fade-in" -->

When we only need a raw pointer from `unique_ptr`
<!-- .element: class="fragment fade-in" -->

```C++
ACTION_TEMPLATE(ExtractPtr,
                HAS_1_TEMPLATE_PARAMS(int, k),
                AND_1_VALUE_PARAMS(pointer)) {
    *pointer = std::get<k>(args).get();
}
```
<!-- .element: class="fragment fade-in" -->
But we will lost it, because `unique_ptr` will be deleted after exit form mock function!

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.8em" -->

<b>This is a very old way, the better one is to just lambda instead, I will show this later</b>
<!-- .element: class="fragment fade-in" -->
___

<!-- .slide: data-background="#ccc" -->
## InSequence (1)

```C++
TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));

    testing::Sequence seq;
    // Four expectations in sequence. There is no override like before
    for (int i = 0; i < 4; ++i) {
        EXPECT_CALL(*mockBarPtr, doOtherStuff)
            .InSequence(seq)
            .WillOnce(Return(i % 2));
    }

    EXPECT_FALSE(foo.doSth("Sth1"));
    EXPECT_TRUE(foo.doSth("Sth2"));
    EXPECT_FALSE(foo.doSth("Sth3"));
    EXPECT_TRUE(foo.doSth("Sth4"));
}
```

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## InSequence (2)

This has the same behaviour like previous example
<!-- .element: class="fragment fade-in" -->

```C++
TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));

    {
        testing::InSequence seq;
        // Four expectations in sequence. There is no override like before
        for (int i = 0; i < 4; ++i) {
            EXPECT_CALL(*mockBarPtr, doOtherStuff).WillOnce(Return(i % 2));
        }
    }

    EXPECT_FALSE(foo.doSth("Sth1"));
    EXPECT_TRUE(foo.doSth("Sth2"));
    EXPECT_FALSE(foo.doSth("Sth3"));
    EXPECT_TRUE(foo.doSth("Sth4"));
}
```
<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## InSequence - branch out

```C++
testing::Sequence s1, s2;

EXPECT_CALL(foo, Method1())
    .InSequence(s1, s2);
EXPECT_CALL(bar, Method2())
    .InSequence(s1);
EXPECT_CALL(bar, Method3())
    .InSequence(s2);
EXPECT_CALL(foo, Method4())
    .InSequence(s2);
```
<!-- .element: class="fragment fade-in" -->

```C++
             +---> Method2 (seq1)
(seq1 seq2)  |
  Method1----|
             |
             +---> Method3 ---> Method4 (seq2)
```
<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## mock non-virtual function (1)

We have the following class
<!-- .element: class="fragment fade-in" -->

```C++
struct Packet {};

class ConcretePacketStream {
public:
    void AppendPacket(Packet* new_packet) {}
    const Packet* GetPacket(size_t packet_number) const {}
    size_t NumberOfPackets() const {}
};
```

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## mock non-virtual function (2)

We can create mock and instead of dynamic polymorphism use static polymorphism (templates)
<!-- .element: class="fragment fade-in" -->

```C++
// A mock packet stream class. It inherits from no other, but defines
// GetPacket() and NumberOfPackets(). No need to add all functions like: AppendPacket
class MockPacketStream {
public:
    // Do not add override!
    MOCK_METHOD(const Packet*, GetPacket, (size_t packet_number), (const));
    MOCK_METHOD(size_t, NumberOfPackets, (), (const));
};

// Now we can use static polymorphism to insert Mock class in a test,
// and real class in production code
template <class PacketStream>
class PacketReader {
public:
    const Packet* ReadPackets(PacketStream* stream, size_t packet_num) {
        return stream->GetPacket(packet_num);
    }
};
```

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.8em" -->
___
<!-- .slide: data-background="#ccc" -->
## mock non-virtual function (3)

Now in test we can use mock class
<!-- .element: class="fragment fade-in" -->

```C++
TEST(TestNonVirtualMethod, ShouldTest) {
    MockPacketStream mock_stream;
    EXPECT_CALL(mock_stream, GetPacket).WillOnce(Return(nullptr));

    PacketReader<MockPacketStream> reader;
    reader.ReadPackets(&mock_stream, 12);
}
```
<!-- .element: class="fragment fade-in" -->

And in production code the real one
<!-- .element: class="fragment fade-in" -->

```C++
ConcretePacketStream stream;
PacketReader<ConcretePacketStream> reader;

auto* packet = reader.ReadPackets(&stream, 12);
```
<!-- .element: class="fragment fade-in" -->

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## StrictMock

The usage of `StrictMock` is similar to normal mock, except that it makes all uninteresting calls failures:

```C++
class MockFoo : public Foo {
    //...
    MOCK_METHOD(void, Fun1, (), (override));
    MOCK_METHOD(void, Fun2, (), (override));
};

TEST(SimpleTest, TestSth) {
  StrictMock<MockFoo> mock_foo;
  // When Fun2 will be also called it cause test failed
  EXPECT_CALL(mock_foo, Fun1());
}
```

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->

## NiceMock

* <!-- .element: class="fragment fade-in" --> The usage of `StrictMock` is similar to normal mock, except that it reject uninteresting calls (we will not see them while run test)
* <!-- .element: class="fragment fade-in" --> NiceMock and StrictMock only affects uninteresting calls (calls of methods with no expectations); they do not affect unexpected calls (calls of methods with expectations, but they don’t match)

```C++
class MockFoo : public Foo {
    //...
    MOCK_METHOD(void, Fun1, (), (override));
    MOCK_METHOD(void, Fun2, (), (override));
};

TEST(SimpleTest, TestSth) {
  NiceMock<MockFoo> mock_foo;
  // When Fun2 will be also called it will be ignored
  EXPECT_CALL(mock_foo, Fun1());
}
```

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## ON_CALL and WillByDefault

We can do whatever we want when some mock method will be called. We can even save all types of arguments, or move objects to test them (call later).
<!-- .element: class="fragment fade-in" -->

When a function takes for instance non-copyable callback, and we need to capture it to continue testing, we can move it inside lambda! This is much better than the tricky template shown before.
<!-- .element: class="fragment fade-in" -->

```C++
TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));

    // Nice way to capture all types of argument
    int* ptr;
    ON_CALL(*mockBarPtr, doOtherStuff)
        .WillByDefault([&ptr](const std::string&, int* new_ptr, const std::vector<int>&) {
            ptr = new_ptr;
            return true;
        });

    EXPECT_CALL(*mockBarPtr, doOtherStuff);
    EXPECT_TRUE(foo.doSth("Sth1"));
    EXPECT_EQ(*ptr, 42);
}
```

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.8em" -->
___
<!-- .slide: data-background="#ccc" -->
## DoAll

If we need to combine a few actions, we can do this inside `doAll(...)`
<!-- .element: class="fragment fade-in" -->

```C++
TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));

    std::string str;
    int* ptr;

    EXPECT_CALL(*mockBarPtr, doOtherStuff)
        .WillOnce(DoAll(
            SaveArg<0>(&str),
            SetArgPointee<1>(80),   // Replace pointer value
            SaveArgPointee<1>(ptr), // Capture value of arg1
            Return(true)));

    EXPECT_TRUE(foo.doSth("Sth1"));
    EXPECT_EQ(str, "Sth1");
    EXPECT_EQ(*ptr, 80);
}
```

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## Invoke (1)

Let's change a little `MockBar`
<!-- .element: class="fragment fade-in" -->

```C++
class MockBar : public Bar {
public:
    ~MockBar() override = default;
    MOCK_METHOD(bool, doOtherStuff, (const std::string&, int*, std::function<void(int)>), (const override));
};
```
<!-- .element: class="fragment fade-in" -->
Now we want to run callback. We can do this without capture it!
<!-- .element: class="fragment fade-in" -->

```C++
EXPECT_CALL(*mockBarPtr, doOtherStuff)
    .WillOnce(DoAll(
        SaveArg<0>(&str),
        SetArgPointee<1>(80),    // Replace pointer value
        SaveArgPointee<1>(ptr),  // Capture value of arg1
        InvokeArgument<2>(500),  // Invoke callback
        Return(true)));
```

<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.9em" -->
___
<!-- .slide: data-background="#ccc" -->
## Invoke (2)

```C++
class Helper {
public:
    void validateArguments(const std::string& str, int* ptr, std::function<void(int)> callback) {
        ASSERT_EQ(str.size(), 4);
        EXPECT_EQ(str, "Sth1");
        ASSERT_TRUE(ptr);
        EXPECT_EQ(*ptr, 42);
        ASSERT_TRUE(callback);
        callback(50);  // We can invoke callback here
    }
};

TEST(ExampleTest, ShouldTest) {
    auto mockBar = std::make_unique<MockBar>();
    auto* mockBarPtr = mockBar.get();
    Foo foo(std::move(mockBar));
    Helper helper;

    EXPECT_CALL(*mockBarPtr, doOtherStuff)
        .WillOnce(DoAll(
            Invoke(&helper, &Helper::validateArguments),
            Return(true)));

    EXPECT_TRUE(foo.doSth("Sth1"));
}
```
<!-- .element: class="fragment fade-in" -->
<!-- .slide: style="font-size: 0.76em" -->
___

## Exercise 2

Open project **SHM** and write test for class `Store.cpp` which will test it's interface. You need to mock `Cargo` class and check if you get correct result based on what you mock. Write mock in `Presentation/exercises/SHM/tests/CargoMock.h` for `Cargo` class.

Go to `Presentation/exercises/SHM/build/test` and run test using command `./SHM_Tests`.