Mocking framework

simendsjo simen.endsjo at pandavre.com
Wed Mar 9 08:11:33 PST 2011


I gave this some thought, and I'm probably just a bit braindamaged by C#.
Consider you wish to unittest a class that fetches data from a database and sends an
email.
The common scenario here is to use IoC and mock the objects so you can check that
"FetchData" was called and "SendEmail" is called using the data from your "FetchData".

So this is the scenario:

interface SomeBigInterface {
    void doStuff();
    // And many more methods here
}

class SomeClassImplementingInterface : SomeBigInterface {
    void doStuff() {}
    // And many more methods here
}

class SomeClass {
    SomeBigInterface _i;
    this(SomeBigInterface i) {
        _i = i;
    }

    void someComplexStuff() {
        _i.doStuff();
    }
}

And how can I mock the entire SomeBigInterface containing 20 methods just to make sure
doStuff is called? And what if it didn't take an interface, but an SmtpClient?

But then I thought I might be forcing D into the limitations of C# and other pure oo
langauges.
Then I created this instead:

// Now I'm only depending on the methods I use, not an entire interface or a specific
class/struct
class SomeClass2(T)
    if( is(typeof({ return T.init.doStuff(); })) )
{
    T _i;
    this(T i) {
        _i = i;
    }

    void someComplexStuff() {
        _i.doStuff();
    }
}

Then I can mock it up a lot easier:

    class MyMock {
        int called;
        void doStuff() { ++called; }
    }

    auto mock = new MyMock();

    auto a = new SomeClass2!MyMock(mock);
    assert(mock.called == 0);
    a.someComplexStuff();
    assert(mock.called == 1);
    a.someComplexStuff();
    assert(mock.called == 2);


And voila.. It's simpler to create the mock object by hand than through a library.
The question is, is this good practice? Should I often just create templates like
isSomeInterface (like the range api does) checking for methods and properties instead of
using interfaces directly?


More information about the Digitalmars-d-learn mailing list