0% found this document useful (0 votes)
23 views123 pages

Unit Testing & GoogleTest Guide

The document discusses unit testing and testability. It describes the objectives of test suites and different levels of testing from unit to system level. It provides examples of unit testing individual components of a program in isolation versus integration and system testing of how components work together.

Uploaded by

Swapnil
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views123 pages

Unit Testing & GoogleTest Guide

The document discusses unit testing and testability. It describes the objectives of test suites and different levels of testing from unit to system level. It provides examples of unit testing individual components of a program in isolation versus integration and system testing of how components work together.

Uploaded by

Swapnil
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 123

CMPT 473

Software Quality Assurance


Unit Testing & Testability
Nick Sumner
with material from the GoogleTest documentation
Test Suite Design
● Objectives
– Functional correctness
– Nonfunctional attributes (performance, ...)
Test Suite Design
● Objectives
– Functional correctness
– Nonfunctional attributes (performance, ...)
● Components – The Automated Testing Pyramid

System UI

API/
Integration/
Component/

Unit
Test Suite Design
● Objectives
– Functional correctness
– Nonfunctional attributes (performance, ...)
● Components – The Automated Testing Pyramid

System UI

API/
Integration/
Component/

Unit
Test Suite Design
● Objectives
– Functional correctness
– Nonfunctional attributes (performance, ...)
● Components – The Automated Testing Pyramid

System UI

API/
Integration/
Component/

Unit
Test Suite Design
● Objectives
– Functional correctness
– Nonfunctional attributes (performance, ...)
● Components – The Automated Testing Pyramid

System UI

API/
Integration/
Component/

Unit
Test Suite Design
● Objectives
– Functional correctness
– Nonfunctional attributes (performance, ...)
● Components – The Automated Testing Pyramid
Integrated
System UI

API/
Integration/
Component/
Isolated Unit
Test Suite Design
● Objectives
– Functional correctness
– Nonfunctional attributes (performance, ...)
● Components – The Automated Testing Pyramid
Integrated Slow
System UI

API/
Integration/
Component/
Isolated Unit Fast
Test Suite Design
● Objectives
– Functional correctness
– Nonfunctional attributes (performance, ...)
● Components – The Automated Testing Pyramid
Integrated Slow
System UI

API/
Integration/
Component/
Isolated Unit Fast
Levels of Testing
● Many different levels of testing can be considered:
– Unit Tests
– Integration Tests
– System Tests
– Acceptance Tests
– …

10
Levels of Testing
● Many different levels of testing can be considered:
– Unit Tests
– Integration Tests
– System Tests
– Acceptance Tests
– …
● The simplest of these is Unit Testing
– Testing the smallest possible fragments of a program

11
Unit Testing
● Try to ensure that the functionality of each component works in
isolation

12
Unit Testing
● Try to ensure that the functionality of each component works in
isolation
– Unit Test a car:
Wheels work. Steering wheel works....

13
Unit Testing
● Try to ensure that the functionality of each component works in
isolation
– Unit Test a car:
Wheels work. Steering wheel works....
– Integration Test a car:
Steering wheel turns the wheels....

14
Unit Testing
● Try to ensure that the functionality of each component works in
isolation
– Unit Test a car:
Wheels work. Steering wheel works....
– Integration Test a car:
Steering wheel turns the wheels....
– System Test a car:
Driving down the highway with the air conditioning on works...

15
Unit Testing
● Try to ensure that the functionality of each component works in
isolation
– Unit Test a car:
Wheels work. Steering wheel works....
– Integration Test a car:
Steering wheel turns the wheels....
– System Test a car:
Driving down the highway with the air conditioning on works....
● Not testing how well things are glued together.

16
Unit Testing
● Try to ensure that the functionality of each component works in
isolation
– Unit Test a car:
Wheels work. Steering wheel works....
– Integration Test a car:
Steering wheel turns the wheels....
– System Test a car:
Driving down the highway with the air conditioning on works....
● Not testing how well things are glued together.
● In practice, there is a lot more debate on this than you might expect

17
Unit Testing
● Try to ensure that the functionality of each component works in
isolation
– Unit Test a car:
Wheels work. Steering wheel works....
– Integration Test a car:
Steering wheel turns the wheels....
– System Test a car:
Driving down the highway with the air conditioning on works....
● Not testing how well things are glued together.
● In practice, there is a lot more debate on this than you might expect
– Degrees of isolation
18
Unit Testing
● Try to ensure that the functionality of each component works in
isolation
– Unit Test a car:
Wheels work. Steering wheel works....
– Integration Test a car:
Steering wheel turns the wheels....
– System Test a car:
Driving down the highway with the air conditioning on works....
● Not testing how well things are glued together.
● In practice, there is a lot more debate on this than you might expect
– Degrees of isolation
– Big & Small vs Unit & Integration
19
Unit Testing
● Try to ensure that the functionality of each component works in
isolation
– Unit Test a car:
Wheels work. Steering wheel works....
– Integration Test a car:
Steering wheel turns the wheels....
– System Test a car:
Driving down the highway with the air conditioning on works....
● Not testing how well things are glued together.
● In practice, there is a lot more debate on this than you might expect

The rapid feedback advantage
Degrees of isolation
– Big & Smallof vs
unitUnit
tests persists for refactoring,
& Integration
– ... but there are judgement calls. 20
Unit Tests
● A dual view:
– They specify the expected behavior of individual components

21
Unit Tests
● A dual view:
– They specify the expected behavior of individual components
– An executable specification

22
Unit Tests
● A dual view:
– They specify the expected behavior of individual components
– An executable specification
● Can even be built first & used to guide development
– Usually called Test Driven Development

23
Unit Tests
● A dual view:
– They specify the expected behavior of individual components
– An executable specification
● Can even be built first & used to guide development
– Usually called Test Driven Development

In practice, the empirical evidence


is against it.

24
Unit Tests
● Some guiding principles:
– Focus on one component in isolation
– Be simple to set up & run
– Be easy to understand

25
Unit Tests
● Some guiding principles:
– Focus on one component in isolation
– Be simple to set up & run
– Be easy to understand
● Usually managed by some automating framework ....

26
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.

27
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions:

TEST(TriangleTest, isEquilateral) {
Triangle tri{2,2,2};
EXPECT_TRUE(tri.isEquilateral());
}

28
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions:

TEST(TriangleTest, isEquilateral) {
Triangle tri{2,2,2};
EXPECT_TRUE(tri.isEquilateral());
}

The TEST macro defines


individual test cases. 29
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions:
The first argument
names related tests.
TEST(TriangleTest, isEquilateral) {
Triangle tri{2,2,2};
EXPECT_TRUE(tri.isEquilateral());
}

30
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions:
The second argument
names individual test cases.
TEST(TriangleTest, isEquilateral) {
Triangle tri{2,2,2};
EXPECT_TRUE(tri.isEquilateral());
}

31
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions:

TEST(TriangleTest, isEquilateral) {
Triangle tri{2,2,2};
EXPECT_TRUE(tri.isEquilateral());
}
EXPECT and ASSERT macros
provide correctness oracles.
32
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions:

TEST(TriangleTest, isEquilateral) {
Triangle tri{2,2,2};
EXPECT_TRUE(tri.isEquilateral());
}
ASSERT oracles terminate the program when they fail.
EXPECT oracles allow the program to continue running. 33
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions.
● TEST() cases are automatically registered with GoogleTest and are
executed by the test driver.

34
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions.
● TEST() cases are automatically registered with GoogleTest and are
executed by the test driver.
● Some tests require common setUp & tearDown
– Group them into test fixtures
– A fresh fixture is created for each test

35
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions.
● TEST() cases are automatically registered with GoogleTest and are
executed by the test driver.
● Some tests require common setUp & tearDown
– Group them into test fixtures
– A fresh fixture is created for each test
– Fixtures enable using the same configuration for multiple tests

36
GoogleTest - Fixtures
class StackTest : public ::testing::Test {
protected:
void SetUp() override {
s1.push(1);
s2.push(2);
s2.push(3);
}

void TearDown() override { }

Stack<int> s1;
Stack<int> s2;
};
Derive from the fixture base class 37
GoogleTest - Fixtures
class StackTest : public ::testing::Test {
protected:
void SetUp() override {
s1.push(1);
s2.push(2);
s2.push(3);
}

void TearDown() override { }

Stack<int> s1;
Stack<int> s2;
}; SetUp() will be called before
all tests using the fixture 38
GoogleTest - Fixtures
class StackTest : public ::testing::Test {
protected:
void SetUp() override {
s1.push(1);
s2.push(2);
s2.push(3);
}

void TearDown() override { }

Stack<int> s1;
Stack<int> s2;
}; TearDown() will be called after
all tests using the fixture 39
GoogleTest - Fixtures

Use the fixture in test cases defined with TEST_F:

TEST_F(StackTest, popOfOneIsEmpty) {
s1.pop();
EXPECT_EQ(0, s1.size());
}

40
GoogleTest - Fixtures

Use the fixture in test cases defined with TEST_F:

TEST_F(StackTest, popOfOneIsEmpty) {
s1.pop();
EXPECT_EQ(0, s1.size());
}

41
GoogleTest - Fixtures

Use the fixture in test cases defined with TEST_F:

TEST_F(StackTest, popOfOneIsEmpty) {
s1.pop();
EXPECT_EQ(0, s1.size());
} {
StackTest t;
t.SetUp();
t.popOfOneIsEmpty();
Behaves like t.TearDown();
}
42
GoogleTest - Fixtures

Use the fixture in test cases defined with TEST_F:

TEST_F(StackTest, popOfOneIsEmpty) {
s1.pop();
EXPECT_EQ(0, s1.size());
}

A different expectation than before!

43
GoogleTest - Fixtures

Use the fixture in test cases defined with TEST_F:

TEST_F(StackTest, popOfOneIsEmpty) {
s1.pop();
EXPECT_EQ(0, s1.size());
}

expected
value
44
GoogleTest - Fixtures

Use the fixture in test cases defined with TEST_F:

TEST_F(StackTest, popOfOneIsEmpty) {
s1.pop();
EXPECT_EQ(0, s1.size());
}

expected observed
value value
45
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions.
● TEST() cases are automatically registered with GoogleTest and are
executed by the test driver.
● Some tests require common setUp & tearDown
● Many different assertions and expectations available
ASSERT_TRUE(condition); EXPECT_TRUE(condition);
ASSERT_FALSE(condition); EXPECT_FALSE(condition);
ASSERT_EQ(expected,actual);
ASSERT_NE(val1,val2);
ASSERT_LT(val1,val2);
EXPECT_EQ(expected,actual);
EXPECT_NE(val1,val2);
EXPECT_LT(val1,val2);

ASSERT_LE(val1,val2); EXPECT_LE(val1,val2); 46
ASSERT_GT(val1,val2); EXPECT_GT(val1,val2);
ASSERT_GE(val1,val2); EXPECT_GE(val1,val2);
GoogleTest
● Increasingly used framework for C++
– Not dissimilar from JUnit, which you have already seen.
● Test cases are written as functions.
● TEST() cases are automatically registered with GoogleTest and are
executed by the test driver.
● Some tests require common setUp & tearDown
● Many different assertions and expectations available
● More information available online
– github.com/google/googletest/blob/master/googletest/docs/Primer.md
– github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md
47
Designing a Unit Test
● Common structure
Designing a Unit Test
● Common structure
TEST_CASE("empty") {
Environment env;
ExprTree tree;

auto result = evaluate(tree, env);

CHECK(!result.has_value());
}
Designing a Unit Test
● Common structure
TEST_CASE("empty") {
Environment env;
ExprTree tree;

auto result = evaluate(tree, env);

CHECK(!result.has_value());
}

This specific test uses


another framework
called Doctest
Designing a Unit Test
● Common structure
Set up a scenario
TEST_CASE("empty") {
Environment env;
ExprTree tree;

auto result = evaluate(tree, env);

CHECK(!result.has_value());
}
Designing a Unit Test
● Common structure
TEST_CASE("empty") {
Environment env;
ExprTree tree; Run the scenario
auto result = evaluate(tree, env);

CHECK(!result.has_value());
}
Designing a Unit Test
● Common structure
TEST_CASE("empty") {
Environment env;
ExprTree tree;

auto result = evaluate(tree, env);

CHECK(!result.has_value());
} Check the outcome
Designing a Unit Test
● Common structure
TEST_CASE("empty") {
Environment env;
ExprTree tree;

auto result = evaluate(tree, env);

CHECK(!result.has_value());
}

This is sometimes known as AAA:


Arrange
Act
Assert
Designing a Unit Test
● Common structure
● Tests should run in isolation
struct Frob {
Frob()
: conn{getDB().connect()}
{ }
DBConnection conn;
};
Designing a Unit Test
● Common structure TEST_CASE("bad test 1") {
Frob frob;
● Tests should run in isolation ...
struct Frob { }
Frob()
: conn{getDB().connect()} TEST_CASE("bad test 2") {
{ } Frob frob;
DBConnection conn; ...
}; }
Designing a Unit Test
● Common structure TEST_CASE("bad test 1") {
Frob frob;
● Tests should run in isolation ...
struct Frob { }
Frob()
: conn{getDB().connect()} TEST_CASE("bad test 2") {
{ } Frob frob;
DBConnection conn; ...
}; }
Designing a Unit Test
● Common structure TEST_CASE("bad test 1") {
Frob frob;
● Tests should run in isolation ...
struct Frob { }
Frob()
: conn{getDB().connect()} TEST_CASE("bad test 2") {
{ } Frob frob;
DBConnection conn; ...
}; }

The order of the test can affect the results!


Designing a Unit Test
● Common structure TEST_CASE("bad test 1") {
Frob frob;
● Tests should run in isolation ...
struct Frob { }
Frob()
: conn{getDB().connect()} TEST_CASE("bad test 2") {
{ } Frob frob;
DBConnection conn; ...
}; }

The order of the test can affect the results!


A flaky DB can affect results!
Designing a Unit Test
● Common structure
● Tests should run in isolation!
Designing a Unit Test
● Common structure
● Tests should run in isolation
struct Frob {
Frob(Connection& inConn)
: conn{inConn}
{ }
Connection& conn;
};
Designing a Unit Test
● Common structure
● Tests should run in isolation
struct Frob {
Frob(Connection& inConn)
: conn{inConn}
{ }
Connection& conn; Dependency injection allows
}; the user of a class to
control its behavior
Designing a Unit Test
● Common structure
● Tests should run in isolation
struct Frob {
Frob(Connection& inConn)
: conn{inConn}
{ }
Connection& conn; Dependency injection allows
}; the user of a class to
control its behavior
Connection
Designing a Unit Test
● Common structure
● Tests should run in isolation
struct Frob {
Frob(Connection& inConn)
: conn{inConn}
{ }
Connection& conn; Dependency injection allows
}; the user of a class to
control its behavior
Connection

DBConnection
Designing a Unit Test
● Common structure
● Tests should run in isolation
struct Frob {
Frob(Connection& inConn)
: conn{inConn}
{ }
Connection& conn; Dependency injection allows
}; the user of a class to
control its behavior
Connection

DBConnection FakeConnection
Designing a Unit Test
● Common structure
● Tests should run in isolation
struct Frob { TEST_CASE("better test 1") {
Frob(Connection& inConn) FakeDB db;
: conn{inConn} FakeConnection conn = db.connect();
{ } Frob frob{conn};
Connection& conn; ...
}; }

Connection

DBConnection FakeConnection
Designing a Unit Test
● Common structure
● Tests should run in isolation
struct Frob { TEST_CASE("better test 1") {
Frob(Connection& inConn) FakeDB db;
: conn{inConn} FakeConnection conn = db.connect();
{ } Frob frob{conn};
Connection& conn; ...
}; }

Connection

More on this later!


DBConnection FakeConnection
Common Patterns (Ammonn & Offutt)
● Checking State
– Final State
● Prepare initial state
● Run test
● Check final state

68
Common Patterns (Ammonn & Offutt)
● Checking State
– Final State
● Prepare initial state
● Run test
● Check final state
– Pre and Post conditions
● Check initial state as well as final state

69
Common Patterns (Ammonn & Offutt)
● Checking State
– Final State
● Prepare initial state
● Run test
● Check final state
– Pre and Post conditions
● Check initial state as well as final state
– Relative effects
● Check final state relative to some initial state

70
Common Patterns (Ammonn & Offutt)
● Checking State
– Final State
● Prepare initial state
● Run test
● Check final state
– Pre and Post conditions
● Check initial state as well as final state
– Relative effects
● Check final state relative to some initial state
– Round trips
● Check behavior on transform/inverse transform pairs

71
Common Patterns (Ammonn & Offutt)
● Checking State
– Final State
● Prepare initial state
● Run test
● Check final state
– Pre and Post conditions
● Check initial state as well as final state
– Relative effects
● Check final state relative to some initial state These have become
– Round trips
fundamental for
testing hard software
● Check behavior on transform/inverse transform pairs

72
Common Patterns (Ammonn & Offutt)
● Checking Interactions/Behavior
– Use mocks

73
Common Patterns (Ammonn & Offutt)
● Checking Interactions/Behavior
– Use mocks
● Testing 'fakes' that verify expected interactions
● http://martinfowler.com/articles/mocksArentStubs.html
● http://googletesting.blogspot.ca/2013/03/testing-on-toilet-testing-state-vs.html

74
Common Patterns (Ammonn & Offutt)
● Checking Interactions/Behavior
– Use mocks
● Testing 'fakes' that verify expected interactions
● http://martinfowler.com/articles/mocksArentStubs.html
● http://googletesting.blogspot.ca/2013/03/testing-on-toilet-testing-state-vs.html

TEST_CASE("better test 1") {


FakeDB db;
FakeConnection conn = db.connect();
Frob frob{conn}; The FakeConnection could check
...
}
that DB interactions are correct.

75
Common Patterns (Ammonn & Offutt)
● Checking Interactions/Behavior
– Use mocks
● Testing 'fakes' that verify expected interactions
● http://martinfowler.com/articles/mocksArentStubs.html
● http://googletesting.blogspot.ca/2013/03/testing-on-toilet-testing-state-vs.html

TEST_CASE("better test 1") {


FakeDB db;
FakeConnection conn = db.connect();
Frob frob{conn}; The FakeConnection could check
...
}
that DB interactions are correct.
NOTE: Test doubles for isolation are good,
76
but mocks should be used sparingly.
Testability
● What makes testing hard?
– Not just difficult to get adequacy
– What makes it difficult to write tests?

77
Testability
● What makes testing hard?
– Not just difficult to get adequacy
– What makes it difficult to write tests?
● Dependencies
– Connections between classes

78
Testability
● What makes testing hard?
– Not just difficult to get adequacy
– What makes it difficult to write tests?
● Dependencies
– Connections between classes
– Singletons

79
Testability
● What makes testing hard?
– Not just difficult to get adequacy
– What makes it difficult to write tests?
● Dependencies
– Connections between classes
– Singletons
– Nondeterminism

80
Testability
● What makes testing hard?
– Not just difficult to get adequacy
– What makes it difficult to write tests?
● Dependencies
– Connections between classes
– Singletons
– Nondeterminism
– Static binding (mitigated by parametric polymorphism)

81
Testability
● What makes testing hard?
– Not just difficult to get adequacy
– What makes it difficult to write tests?
● Dependencies
– Connections between classes
– Singletons
– Nondeterminism
– Static binding
– Mixing construction & application logic
– ...

82
Testability
● What makes testing hard?
– Not just difficult to get adequacy
– What makes it difficult to write tests?
● Dependencies
– Connections between classes
– Singletons
– Nondeterminism
– Static binding
– Mixing construction & application logic
– ...
But solutions exist!
You can design code to be testable! 83
Testability (by example)
● Next week (?) we will work together to improve some difficult to test
code....

84
Testability
● Keys things to notice:
– Mocks & stubs allow us to isolate components under test

85
Testability
● Keys things to notice:
– Mocks & stubs allow us to isolate components under test
– Dependency Injection allows us to use mocks and stubs as necessary

86
Testability
● Keys things to notice:
– Mocks & stubs allow us to isolate components under test
– Dependency Injection allows us to use mocks and stubs as necessary
– But doing this can lead to a lot more work and boilerplate code when
written by hand

87
Testability
● Keys things to notice:
– Mocks & stubs allow us to isolate components under test
– Dependency Injection allows us to use mocks and stubs as necessary
– But doing this can lead to a lot more work and boilerplate code when
written by hand

Given dependency injection,


what happens to the way we create objects?
88
Testability
● Keys things to notice:
– Mocks & stubs allow us to isolate components under test
– Dependency Injection allows us to use mocks and stubs as necessary
– But doing this can lead to a lot more work and boilerplate code when
written by hand

Given dependency injection,


what happens to the way we create objects?
How might we mitigate
boilerplate issues? 89
Mocking Framework Example
● Frameworks exist that can automate the boilerplate behind:

90
Mocking Framework Example
● Frameworks exist that can automate the boilerplate behind:
– Mocking
e.g. GoogleMock, Mockito, etc.

91
Mocking Framework Example
● Frameworks exist that can automate the boilerplate behind:
– Mocking
● e.g. GoogleMock, Mockito, etc.
– Dependency Injection
e.g. Google Guice, Pico Container, etc.

92
Using GoogleMock
● Steps:
1) Derive a mock class from the class you wish to fake

93
class Thing {
Using GoogleMock public:
virtual int foo(int x);
virtual void bar(int y);
● Steps: };
1) Derive a mock class from the class you wish to fake

94
class Thing {
Using GoogleMock public:
virtual int foo(int x);
virtual void bar(int y);
● Steps: };
1) Derive a mock class from the class you wish to fake

class MockThing : public Thing {


public:
...
MOCK_METHOD(int, foo, (int x), (override));
MOCK_METHOD(void, bar, (int y), (override));
};

95
class Thing {
Using GoogleMock public:
virtual int foo(int x);
virtual void bar(int y);
● Steps: };
1) Derive a mock class from the class you wish to fake
2) Replace virtual calls with uses of MOCK_METHOD().

class MockThing : public Thing {


public:
...
MOCK_METHOD(int, foo, (int x), (override));
MOCK_METHOD(void, bar, (int y), (override));
};

96
Using GoogleMock
● Steps:
1) Derive a mock class from the class you wish to fake
2) Replace virtual calls with uses of MOCK_METHOD().
3) Use the mock class in your tests.

97
Using GoogleMock
● Steps:
1) Derive a mock class from the class you wish to fake
2) Replace virtual calls with uses of MOCK_METHOD().
3) Use the mock class in your tests.
4) Specify expectations before use via EXPECT_CALL().
● What arguments? How many times? In what order?

InSequence dummy;
EXPECT_CALL(mockThing, foo(Ge(20)))
.Times(2)
.WillOnce(Return(100))
.WillOnce(Return(200));
EXPECT_CALL(mockThing, bar(Lt(5))); 98
Using GoogleMock
● Steps:
1) Derive a mock class from the class you wish to fake
2) Replace virtual calls with uses of MOCK_METHOD().
3) Use the mock class in your tests.
4) Specify expectations before use via EXPECT_CALL().

This is part of the Arrange
What arguments? How many times? In what order?
in AAA.
InSequence dummy;
EXPECT_CALL(mockThing, foo(Ge(20)))
.Times(2)
.WillOnce(Return(100))
.WillOnce(Return(200));
EXPECT_CALL(mockThing, bar(Lt(5))); 99
Using GoogleMock
● Steps:
1) Derive a mock class from the class you wish to fake
2) Replace virtual calls with uses of MOCK_METHOD().
3) Use the mock class in your tests.
4) Specify expectations before use via EXPECT_CALL().
● What arguments? How many times? In what order?
5) Expectations are automatically checked in the destructor of the mock.

100
Using GoogleMock
● Precisely specifying mock behavior

InSequence dummy;
EXPECT_CALL(mockThing, foo(Ge(20)))
.Times(2) // Can be omitted here
.WillOnce(Return(100))
.WillOnce(Return(200));
EXPECT_CALL(mockThing, bar(Lt(5)));

101
Using GoogleMock
● Precisely specifying mock behavior

InSequence dummy;
EXPECT_CALL(mockThing, foo(Ge(20)))
.Times(2) // Can be omitted here
.WillOnce(Return(100))
.WillOnce(Return(200));
EXPECT_CALL(mockThing, bar(Lt(5)));

102
Using GoogleMock
● Precisely specifying mock behavior

InSequence dummy;
EXPECT_CALL(mockThing, foo(Ge(20)))
.Times(2) // Can be omitted here
.WillOnce(Return(100))
.WillOnce(Return(200));
EXPECT_CALL(mockThing, bar(Lt(5)));

103
Using GoogleMock
● Precisely specifying mock behavior

InSequence dummy;
EXPECT_CALL(mockThing, foo(Ge(20)))
.Times(2) // Can be omitted here
.WillOnce(Return(100))
.WillOnce(Return(200));
EXPECT_CALL(mockThing, bar(Lt(5)));

104
Using GoogleMock
● Precisely specifying mock behavior

InSequence dummy;
EXPECT_CALL(mockThing, foo(Ge(20)))
.Times(2) // Can be omitted here
.WillOnce(Return(100))
.WillOnce(Return(200));
EXPECT_CALL(mockThing, bar(Lt(5)));

105
Using GoogleMock
● Precisely specifying mock behavior

InSequence dummy;
EXPECT_CALL(mockThing, foo(Ge(20)))
.Times(2) // Can be omitted here
.WillOnce(Return(100))
.WillOnce(Return(200));
Complex behaviors canbar(Lt(5)));
EXPECT_CALL(mockThing, be checked
using these basic pieces.
106
Using GoogleMock
● Note, GoogleMock can use the same process for creating
both stubs and mocks as well as test fakes in the middle.

107
Using GoogleMock
● Note, GoogleMock can use the same process for creating
both stubs and mocks as well as test fakes in the middle.
● A mock will check that a function is called in the right ways.

108
Using GoogleMock
● Note, GoogleMock can use the same process for creating
both stubs and mocks as well as test fakes in the middle.
● A mock will check that a function is called in the right ways.
● A stub will prevent interaction with external resources and possibly
return fake data.

109
Using GoogleMock
● Note, GoogleMock can use the same process for creating
both stubs and mocks as well as test fakes in the middle.
● A mock will check that a function is called in the right ways.
● A stub will prevent interaction with external resources and possibly
return fake data.

What might this imply about


where you use mocks vs
where you use stubs?
110
Using GoogleMock
● How would I stub out a database connection?

111
Using GoogleMock
● How would I stub out a database connection?
struct Frob {
Frob(Connection& inConn)
: conn{inConn}
{ }
Connection& conn;

int doThing() {

x = conn.readValue();

}
};
112
Using GoogleMock
● How would I stub out a database connection?
struct Frob {
Frob(Connection& inConn) TEST(FrobTests, doesThing) {
: conn{inConn} FakeDBConnection conn;
{ } EXPECT_CALL(conn, readValue())
Connection& conn; .WillOnce(Return(5));

int doThing() { Frob frob{conn};


… auto result = frob.doThing();
x = conn.readValue();
… ASSERT(42, result);
} }
};
113
Using GoogleMock
● How would I stub out a database connection?
struct Frob {
Frob(Connection& inConn) TEST(FrobTests, doesThing) {
: conn{inConn} FakeDBConnection conn;
Arrange
{ } EXPECT_CALL(conn, readValue())
Connection& conn; .WillOnce(Return(5));

int doThing() { Act Frob frob{conn};


… auto result = frob.doThing();
x = conn.readValue();
… Assert ASSERT(42, result);
} }
};
114
Using GoogleMock
● How would I check (mock) writing to a database connection?

115
Using GoogleMock
● How would I check (mock) writing to a database connection?
struct Frob {
Frob(Connection& inConn)
: conn{inConn}
{ }
Connection& conn;

int doThing() {

conn.writeValue(x);

}
};
116
Using GoogleMock
● How would I check (mock) writing to a database connection?
struct Frob {
Frob(Connection& inConn)
: conn{inConn}
TEST(FrobTests, doesThing) {
{ }
FakeDBConnection conn;
Connection& conn;
EXPECT_CALL(conn, writeValue(Eq(42)));
int doThing() {
Frob frob{conn};

auto result = frob.doThing();
conn.writeValue(x);
}

}
};
117
Using GoogleMock
● How would I check (mock) writing to a database connection?
struct Frob {
Frob(Connection& inConn)
: conn{inConn}
TEST(FrobTests, doesThing) {
{ }
FakeDBConnection conn;
Connection& conn; Arrange
EXPECT_CALL(conn, writeValue(Eq(42)));
int doThing() {
Act Frob frob{conn};

auto result = frob.doThing();
conn.writeValue(x);
}

}
};
118
Using GoogleMock
● How would I check (mock) writing to a database connection?
struct Frob {
Frob(Connection& inConn)
: conn{inConn}
TEST(FrobTests, doesThing) {
{ }
FakeDBConnection conn;
Connection& conn; Arrange
EXPECT_CALL(conn, writeValue(Eq(42)));
int doThing() {
Act Frob frob{conn};

auto result = frob.doThing();
conn.writeValue(x);
}

}
}; Assert
119
Summary
● Unit testing provides a way to automate much of the testing process.

120
Summary
● Unit testing provides a way to automate much of the testing process.
● Testing small components bootstraps confidence in the system on
confidence in its constituents.

121
Summary
● Unit testing provides a way to automate much of the testing process.
● Testing small components bootstraps confidence in the system on
confidence in its constituents.
● Tests can verify state or behaviors.

122
Summary
● Unit testing provides a way to automate much of the testing process.
● Testing small components bootstraps confidence in the system on
confidence in its constituents.
● Tests can verify state or behaviors.
● Software must be designed for testing (or designed by testing)

123

You might also like