dhasenan
Joined: 03 Feb 2005 Posts: 73 Location: New York
|
Posted: Sun Nov 11, 2007 10:06 am Post subject: dmocks: problems |
|
|
dmocks will be mostly complete shortly. But even when it's complete, it won't be *useable*.
The problem is this. I can use a constructor to get around mocks. So, in order to use mocks, I have to pass in all of a class's dependencies as constructor arguments. That is:
Code: |
class Foo {
this () {
_dbConnection = new DbConnection();
}
}
|
gets replaced by:
Code: |
class Foo {
this (DbConnection c) {
_dbConnection = c;
}
}
class FooFactory {
Foo getFoo () { return new Foo(new DbConnection()); }
}
|
And it's slightly worse if you need Foo to be a singleton.
Then your tests in other places change from:
Code: |
unittest {
auto mocker = new Mocker;
auto foo = mocker.Mock!(Foo);
auto target = new Whatever(foo);
...
}
|
to:
Code: |
unittest {
auto mocker = new Mocker;
auto foo = mocker.Mock!(Foo);
auto fooFactory = mocker.Mock!(FooFactory);
mocker.Expect(fooFactory.getFoo()).Return(foo);
auto target = new Whatever(fooFactory);
...
}
|
It's ugliness, it's repetitive, and it's servile. DO NOT WANT.
For mocks to work decently, without much trouble, I need to create a dependency injection tool. Then you can write your simple and beautiful unittests with dmocks, and you can avoid writing factories.
I'm planning on an interface like this:
Code: |
// Foo is a singleton:
class Foo : Bar, Singleton {}
// Bar is probably an abstract class, and implemented by Foo
class Bar : IBar, ImplementedBy!(Foo) {}
// IBar is an interface that's implemented by Bar
interface IBar : ImplementedBy!(Bar) {}
// Fredchook has a dependency on IBar
class Fredchook : IRatgarb {
this (IBar bar) {...}
}
interface IRatgarb {}
void main () {
auto builder = new ObjectBuilder();
builder.Bind!(IRatgarb, Fredchook);
auto chook1 = builder.Get!(IRatgarb); // builds a Fredchook, making a Foo
auto chook2 = builder.Get!(IRatgarb); // builds a second Fredchook, using previous Foo
}
|
Comments? |
|