开发者

Simplifying Testing through design considerations while utilizing dependency injection

开发者 https://www.devze.com 2022-12-24 20:23 出处:网络
We are a few months into a green-field project to rework the Logic and Business layers of our product. By utilizing MEF (dependency injection) we have achieved high levels of code coverage and I belie

We are a few months into a green-field project to rework the Logic and Business layers of our product. By utilizing MEF (dependency injection) we have achieved high levels of code coverage and I believe that we have a pretty solid product. As we have been working through some of the more complex logic I have found it increasingly difficult to unit test.

We are utilizing the CompositionContainer to query for types required by these complex algorithms. My unit tests are sometimes difficult to follow due to the lengthy mock object setup process that must take place, just right, to allow for certain circumstances to be verified. My unit tests often take me longer to write than the code that I'm trying to test.

I realize this is not only an issue with dependency injection but with design as a whole. Is poor method design or lack of composition to blame for my overly complex tests? I've tried base classing tests, creating commonly used mock objects and ensuring that I utilize the container as much as possi开发者_C百科ble to ease this issue but my tests always end up quite complex and hard to debug. What are some tips that you've seen to keep such tests concise, readable, and effective?


My subjective viewpoint:

  • MEF looks like a really nice plug-in framework; it's not designed to be a full-fledged DI framework. If you don't need the live swappable components, investigate full DI/IoC Container frameworks. Unity is Microsoft's alternative.
  • Make sure you are not doing the Service Locator anti-pattern. Use constructor injection of interfaces whenever possible. See this great post by Mark Seemann and this one by Jimmy Bogard. Your statement that you "utilize the container as much as possible" is a concern - few classes need to know anything about the container.
  • Get a really good mocking/isolation framework and learn to use it well. I love Moq. Try to do state verification on the system under test rather than behavior verification on the mock whenever possible.
  • Read The Art of Unit Testing. Read other books and articles on unit testing. Practice TDD. Keep learning.
  • Read Clean Code and insure that your classes follow the SOLID principles (especially the Single Responsibility Principle). Lengthy mock setup is a code smell; your classes are probably doing too much. High code coverage is nice, but a better metric might be cyclomatic complexity.
  • Don't worry about your unit tests taking longer to write than the production code. Treat your tests like production code, though, and remove duplication whenever you can preserve readability and maintainability.


Here are some good links about DI and good design practices (in terms of writing testable code) that you might want to check (google tech talks):

  • Clean Code Talks - Don't Look For Things!
  • Clean Code Talks - "Global State and Singletons"
  • Clean Code Talks - "GuiceBerry"

I found them very helpful with plenty of good tips on testable design.

0

精彩评论

暂无评论...
验证码 换一张
取 消