Przejdź do głównej zawartości


Wyświetlanie postów z luty, 2013

Recommended reading: Clean Code

A week ago I started reading Uncle Bob's book "Clean Code". Although I'm still not yet half way through the book, I want to recommend this book to anyone who has not read it yet. One of the many things that impressed me during the reading was this:

In in the book, Robert Martin makes several times the point that the bad code, such as one with long functions, many indentation levels, cryptic names and complicated conditional expressions inside those functions is simply hard to read. This may be an astonishing this to hear from a professional, at a first glance. Indeed, through our education and early professional work we become used to the notion that "real professional" is able to decypher really complicated code without a hitch. We are also often impressed by our colleagues who through years of dedicated work have become fluent in understanding of extremely bad written and uncomprehensible modules.

Martin tells us that this is not the right way to look at …

Code Kata: Recently opened files

Kata #2: Recently opened files

Implement a container that has the well known functionality of "Recently opened files" that you know from various applications you use:
the container must be able to list file paths that it storesif file A is opened and right after that we ask the container to list the file paths it stores, the path to file A will be listed as the first onethe number of stored file paths is limited; when the limit is exceeded the container forgets least recently used file pathin the list of recently open files, each file path can appear once and only once

Code Kata: Vending Machine

Kata #1: Vending Machine

Your task is to implement a piece of software for a vending machine that sells sweets. The machine accepts coins and must be capable of returning change. It is up to you to decide on how inserted coins and change that is given out are represented. Consider the following variations of this exercise:
Simplification: you have an unlimited number of coins of every kindRealistic: the machine is loaded with coins at the beginning and you have a limit on the number of coins of every kindMore realistic: the machine adds the inserted coins to respective coin slots and uses them to serve further transactionsEven more realistic: the machine tries to optimize the way of giving out coins - if there is danger of giving out too many coins of kind A, and there are is surplus of coins of kind B, then more of B coins are used to produce changeFuturistic: the machine asks you to provide it with coins that would help it return the proper change How would your implementatio…

Piotr's Less Obvious Advice on Google Mock: State maintenance

Google Mock provides several ways to maintain state inside mock objects. One way of implementing state maintenance is with SaveArg. Consider the following example.

We have a class Configurator, which allows a caller to set and get values of a parameter:

class Configurator

    virtual ~Configurator() {}

    virtual void setParamX(int n) = 0;
    virtual int getParamX() = 0;

And we have a class Client that calls Configurator's methods and it also has a method incParamXBy, that can be used to increase the current value of paramX by a certain value.

class Client

    Client(Configurator & cfg);
    virtual ~Client() {}

    void setParamX(int n);
    void incParamXBy(int n);
    int getParamX();


    Configurator & _cfg;

incParamXBy internally calls setParamX and getParamX on Configurator:

void Client::incParamXBy(int n)
    _cfg.setParamX(_cfg.getParamX() + n);

Let's assume that the initial value of paramX is A and that we want to increase paramX by…

Piotr's Less Obvious Advice on Google Mock: Returning new objects from a mock

Google Mock provides a way to return newly created objects from a mock method. Suppose we have a  Generator class that is supposed to generate new objects when createNewRecord method is called:

class Generator
    virtual ~Generator() {}
    virtual Record * createNewRecord() = 0;

...and suppose we want to mock this class:

class MockGenerator : public Generator
    MOCK_METHOD0(createNewRecord, Record * ());

Suppose the caller class Client has run method defined as follows:

void Client::run()
    for(int i = 0; i < 3; i++)
        rec_tab[i] = gen.createNewRecord();

We want the mock to return a pointer to a new object each time createNewRecord is called. This is how we can express this in the test code:

TEST(ClientTest, CanRun)
    MockGenerator gen;
    Client c(gen);

    EXPECT_CALL(gen, createNewRecord())
                 //this is equivalent of returning new Record(1,2,3)

Piotr's Less Obvious Advice on Google Mock: Mutual method calls

Imagine that object A calls method M of object B and B is a mock object. Let's assume further that if B were real, calling the M method would result in B calling a method on A (M would call an A's method from its body). Suppose we want to simulate the same behavior with a mock object. We have a "master" and "slave" objects called Starter and Startee, respectively.

class Starter
  Starter(Startee & startee, int vol);
  virtual ~Starter() {}

  void start();
  void configure();

  Startee & startee_;
  int vol_;


// implementation of the above Starter methods
Starter::Starter(Startee & startee, int vol) : startee_(startee), vol_(vol)

// Starter will call run method on startee
void Starter::start()

// this method is supposed to be called by Startee as a result of calling
void Starter::configure()

And now, Startee:

class Startee

  virtual ~Startee() {}


Piotr's Less Obvious Advice on Google Mock: Mocking destructors

Can we verify that a mock object is properly destroyed? Of course! There is a couple of subtle differences between mocking regular functions and mocking destructors. Let's suppose we have a Grinder object that destroys any Piece object passed to its grind method:

void Grinder::grind(Piece * piece) {
  delete piece;

Furthermore, Grinder can accumulate a list of Pieces (actually, let it be a list of pointers to Pieces) for destruction that will take place when Grinder itself is destroyed. To add a Piece to the list, we define:

int Grinder::enqueue_piece(Piece * piece) {
  return list_of_pieces_.size();

Now, to keep the promise of destroying the queued pieces, Grinder's destructor is defined as follows:

Grinder::~Grinder() {
  for(list<Piece*>::iterator it = list_of_pieces_.begin(); it != list_of_pieces_.end(); it++) {
    delete *it;


But how can we mock the destructor of Piece so that we can verify that Grinder really destroys Piec…

Piotr's Less Obvious Advice on Google Mock: Assigning values through method calls

On many occasions, we may want to test a real object by passing to it prepared buffers of data (characters, bytes, etc.) that are filled in when the object calls a mock method. This can be achieved by using SetArrayArg.

Suppose we have a Client object that implements a find method, which takes an array of characters as input argument. The method queries a Driver object for chunks of data (other arrays of characters of the same size as the input argument) and compares each chunk with the input array:

void Client::find(char * buf)
    char tmp_buf[buflen];
    bool found = false;

    while(!found && _drv.getDataChunk(tmp_buf))
        int i = 0;
        while(i < buflen && buf[i] == tmp_buf[i])

        if(i == buflen)
            found = true;

        cout << "Found matching chunk of data." << endl;
        cout << "No matching chunk of data found." << endl;