Virtual methods in constructors for TDD using Extract And Override pattern
I want to use Extract And Override pattern in my code, the pattern is: Extract a method that creates an object needed in code make it virtual and override the methods in the TextFixture where it creates a fake stub object, I have read about this in The Art Of Unit Testing.
Now I finally found a place where this idea can be used but the method is called in the constructor of my object, and VS displays a warning saying that the constructor contains a virtual method, not I see why this might be a problem because it's an easy way to break the code in the future.
My question is, does the benefits of testable code overshoot the problem that this mi开发者_JAVA技巧ght cause in the future?
This is a problem that TDD enthusiasts often solve using IoC- the idea is that rather than constructing the object being tested in the constructor, you pass it to the constructor using your IoC container. Then for tests, you configure your IoC container to use a mock object.
Constructor should be dumb - it should construct the object. If your class requires complex initialization it should have a separate initialization method. If the initialization can be overriden in derived class, the separate method is a must. The problem with calling a virtual method in constructor is that it can call code from derived type before the type is initialized.
This is nicely implemented in Spring.NET where each object registration can have registered initialization and destruction methods. Initialization method is called after the object is constructed and all dependencies injected. I think other IoC containers have this feature as well.
If you ignore this warning, you assume that the derived class does not care about not being initialized before your method is called. This applies also to the derived class generated for your unit tests.
Even if it seems to work, this may break if the implementation of your mocking framework changes. Or, it might start to care when you register constraints for the method call.
So get rid of the virtual in the constructor.
精彩评论