subcommanderblog.wordpress.com

Subcommander Development Blog

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 ,

One Response

Subscribe to comments with RSS.

  1. Interesting. I’m going to check out google mock now.

    You might be interested my post here about testing proxy models:

    http://steveire.wordpress.com/2009/06/23/testing-non-trivial-generic-proxy-models/

    The tests have advanced since then, but I’m about to start another refactoring of the tests.

    steveire

    Thursday, 12 November, 2009 at 11:48


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: