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?

Reply via email to