Specifically, I was TDDing an object that had many dependencies injected through the constructor. Basically what happened was each new test introduced a new dependency, which causes the previous tests to have to be updated. For example:
[Test] public void Test1() { var testobj = new Testobj( new Mock<ISomething>().Object ); }I'm using moq here, and creating a default partial mock, which takes care of itself.
Then I write the next test:
[Test] public void Test2() { var setupMock = new Mock<ISomething>(); // setup the mock var testobj = new Testobj( setupMock.Object, new Mock<ISomethingElse>().Object ); }Notice this test has introduced a new dependency, ISomethingElse. Now the first test wont compile, we have to go update it and add the mock for ISomethingElse. This will continue with each test that introduces a new dependency causing every previous test to be updated.
You could simply refactor the constructor into a helper method so you only have to change it in one place. But this doesn't work so well when the tests are passing in their own mocks. You'd need lots of helper methods with lots of different method overloads. Enter optional and default parameters!
public Testobj BuildTestobj(Mock<ISomething> something = null, Mock<ISomethingElse> somethingElse = null ) { return new Testobj( ( something ?? new Mock<ISomething>() ).Object, ( somethingElse ?? new Mock<ISomethingElse>() ).Object ); }Now we can update the tests:
[Test] public void Test() { var testobj = BuildTestobj(); } [Test] public void Test2() { var setupMock = new Mock<ISomething>();Simple, clean, refactor friendly, and your tests are now nicely decoupled from the constructor's method signature!// setup the mockvar testobj = BuildTestobj( something = setupMock ); }
I posted some related thoughts: http://twoguysarguing.wordpress.com/2010/11/20/mocking-frameworks-are-like-cologne/
ReplyDelete