subcommanderblog.wordpress.com

Subcommander Development Blog

Posts Tagged ‘mock

creating a custom QAbstractProxyModel – Google Mock

with one comment

Part I redone, getting started using Google Mock.

A while ago I started to build a custom QAbstractProxyModel for subcommanders working copy view in creating a custom QAbstractProxyModel.

A few weeks ago I red about Google Mock, a mock framework for C++ and I planned to try it. There is a nice, simple and short introduction: Google Mock for Dummies.

In the last creating a custom QAbstractProxyModel article I created a simple mock from scratch that is simple enough for a first try. So the goal is to simplify that. If it doesn’t simplify that code, why would I want to use a mock framework? :)

Here is the original hand made mock class and test. Constructor and destructor connect and disconnect the signals from src (that is the proxy model) to the slots and verify is used to verify the results.

class SignalTarget : public QObject
{
  Q_OBJECT;

public:
  SignalTarget( QObject* src );
  ~SignalTarget();

  virtual void verify();

public slots:
  void modelAboutToBeReset();
  void modelReset();

private:
  QObject* _src;

protected:
  int  _hitModelAboutToBeReset;
  int  _hitModelReset;
};

To check that the tested class (the proxy model) properly emits the signals, I subclassed SignalTarget to ASSERTS that the slots were called as many times as they should. Here is the test code:

void WcViewItemProxyModelTest::emitsModelResetSignals()
{
  class Target : public SignalTarget {
  public:
    Target( QObject* src ) : SignalTarget(src) {
    }

    void verify() {
      CPPUNIT_ASSERT_EQUAL( 1, _hitModelAboutToBeReset );
      CPPUNIT_ASSERT_EQUAL( 1, _hitModelReset );
    }
  };

  Target target(_proxy);
  _proxy->reset();
  target.verify();
}

Using Google Mock this gets a bit simpler. The basic mock class get a bit shorter because I no longer need the verify method and the int counters. Google Mock will take care of it:

class SignalTarget : public QObject
{
  Q_OBJECT; 

public:
  SignalTarget( QObject* src );
  ~SignalTarget(); 

public slots:
  void modelAboutToBeReset();
  void modelReset(); 

private:
  QObject* _src;
};

To a create the actual mock class I derive a new class from SignalTarget and tell it to mock the ...Reset() methods by using the MOCK_METHODx macro:

class MockSignal : SignalTarget
{
public:
  MockSignal(QObject* target) : SignalTarget(target) {
  }

  MOCK_METHOD0(modelAboutToBeReset, void());
  MOCK_METHOD0(modelReset, void());
};

Finally I create the mock object in the test and set the expectations (the methods should be called 1 time) by using the EXPECT_CALL macro and calling Times with the expected number of calls. This is a lot simpler than creating the mock class in the original code to set up the expectations in the verify() method.

void WcViewItemProxyModelTest::emitsModelResetSignals()
{
  MockSignal mtarget(_proxy);
  EXPECT_CALL(mtarget, modelAboutToBeReset()).Times(1);
  EXPECT_CALL(mtarget, modelReset()).Times(1);

  _model->reset();
}

All in all it was quite easy to get started with Google Mock. Although I used it only on a very simple example I think it is a nice help for writing tests. If it fits the thing you want to test it can reduce the code noise required to set up the test.

If you write tests in c++, check it out.. :-)

Advertisements

Written by hauner

Wednesday, 3 June, 2009 at 21:42

Posted in subcommander

Tagged with ,