What kind of practices do you use to make your code more unit testing friendly?
相关问题
- Dependencies while implementing Mocking in Junit4
- How to unit test a reactive component where ngCont
- TestCafe - The browser always starts in clean slat
- Access for global variables JavaScript unit testin
- Name for a method that has only side effects
相关文章
- How to replace file-access references for a module
- How to mock methods return object with deleted cop
- What is a good way of cleaning up after a unit tes
-
EF6 DbSet
returns null in Moq - React testing library: Test attribute / prop
- React/JestJS/Enzyme: How to test for ref function?
- Should client-server code be written in one “proje
- Algorithm for maximizing coverage of rectangular a
Check up this talk Automated Testing Patterns and Smells. One of the main take aways for me, was to make sure that the UnitTest code is in high quality. If the code is well documented and well written, everyone will be motivated to keep this up.
TDD -- write the tests first, forces you to think about testability and helps write the code that is actually needed, not what you think you may need
Refactoring to interfaces -- makes mocking easier
Public methods virtual if not using interfaces -- makes mocking easier
Dependency injection -- makes mocking easier
Smaller, more targeted methods -- tests are more focused, easier to write
Avoidance of static classes
Avoid singletons, except where necessary
Avoid sealed classes
I'm continually trying to find a process where unit testing is less of a chore and something that I actually WANT to do. In my experience, a pretty big factor is your tools. I do a lot of ActionScript work and sadly, the tools are somewhat limited, such as no IDE integration and lack of more advanced mocking frameworks (but good things are a-coming, so no complaints here!). I've done test driven development before with more mature testing frameworks and it was definately a more pleasurable experience, but still felt like somewhat of a chore.
Recently however I started writing code in a different manner. I used to start with writing the test, watching them fail, writing code to make the test succeed, rinse and repeat and all that.
Now however, I start with writing interfaces, almost no matter what I'm going to do. At first I of course try to identify the problem and think of a solution. Then I start writing the interfaces to get a sort of abstract feel for the code and the communication. At that point, I usually realize that I haven't really figured out a proper solution to the problem at all as a result of me not fully understanding the problem. So I go back, revise the solution and revise my interfaces. When I feel that the interfaces reflect my solution, I actually start with writing the implementation, not the tests. When I have something implemented (draft implementationd, usually baby steps), I start testing it. I keep going back between testing and implementing, a few steps forward at a time. Since I have interfaces for everything, it's incredibly easy to inject mocks.
I find working like this, with classes having very little knowledge of other implementation and only talking to interfaces, is extremely liberating. It frees me from thinking about the implementation of another class and I can focus on the current unit. All I need to know is the contract that the interface provides.
But yeah, I'm still trying to work out a process that works super-fantastically-awesomely-well every time.
Oh, I also wanted to add that I don't write tests for everything. Vanilla properties that don't do much but get/set variables are useless to test. They are garuanteed by the language contract to work. If they don't I have way worse problems than my units not being testable.
And something that you learn the first thing in OOP, but so many seems to forget: Code Against Interfaces, Not Implementations.
Spend some time refactoring untestable code to make it testable. Write the tests and get 95% coverage. Doing that taught me all I need to know about writing testable code. I'm not opposed to TDD, but learning the specifics of what makes code testable or untestable helps you to think about testability at design time.