New code
Aim: Testable code
SOLID & GRASP principles, design patterns,
TDD, etc.
Slide 14
Slide 14 text
Dependency
Injection
programming against abstractions
Slide 15
Slide 15 text
// Constructor DI
class Data {
public:
bool empty() = 0;
int count() = 0;
};
class ConcreteData : public Data {...};
class FakeData : public Data {...};
class Processor {
public:
Processor(Data* data);
};
Slide 16
Slide 16 text
// Setter DI
class Data {
public:
bool empty() = 0;
int count() = 0;
};
class ConcreteData : public Data {...};
class FakeData : public Data {...};
class Processor {
public:
Processor();
void SetData(Data* data) { d_ = d; }
Slide 17
Slide 17 text
// Template DI
template
class Processor {
public:
Processor();
private:
T data_;
};
// Production code
Processor p;
// Testing code
Processor p;
Slide 18
Slide 18 text
Legacy code
characterization tests, not too strict about
FIRST principles of unit testing, I prefer to
have classes in test harnesses
Slide 19
Slide 19 text
Decoupling
dependencies
using preprocessing and linking stages
Legacy Code
// Preprocessing
// DbRecord.cpp
#include "Pre.h"
#include "DbRecord.h"
...
// DbRecordTests.cpp
#include "Pre.h"
#include "DbRecord.h"
class MysqlStub { ... };
...
// Pre.h -> Different in tests
// than in production code
#define Mysql MysqlStub
Legacy Code
Slide 22
Slide 22 text
// Linking
// BFake.cpp
class B { ... };
// ATests.cpp
#include "A.h" // It will include "B.h"
TEST(...) { }
// Compile BFake.cpp instead of B.cpp
Legacy Code
Slide 23
Slide 23 text
Accessing private
methods and
variables
Sometimes you don't have a choice...
Legacy Code
Slide 24
Slide 24 text
No content
Slide 25
Slide 25 text
// Option 1: Review your design!!!
Slide 26
Slide 26 text
// Option 1: Review your design!!!
// Option 2: Getters
class A {
public:
const Obj& getObject() const {
return obj;
}
private:
Obj obj;
};
Slide 27
Slide 27 text
// Option 1: Review your design!!!
// Option 2: Getters
// Option 3: Add testing functions
class A {
public:
...
bool DoSomeCheckUsingPrivateStuff();
private:
...
};
Slide 28
Slide 28 text
// Option 1: Review your design!!!
// Option 2: Getters
// Option 3: Add testing functions
// Option 4: Make some friends :)
class MyClass {
private:
// Google Test macro
FRIEND_TEST(MyClassTest, MyMethod);
};
Slide 29
Slide 29 text
// Option 1: Review your design!!!
// Option 2: Getters
// Option 3: Add testing functions
// Option 4: Make some friends :)
// Option 5: Redefine private/protected
// MyClassTests.cpp
#define private public
#include "MyClass.h"
MyClass my_class;
my_class.private_method();