In the previous post in this series (“last week” to those who didn’t read it over a year ago), I made simple code complicated in the effort to make it unit testable. It was all going along fine, until I started bringing functional programming into the mix.
Since that worked so well, I’m going to demonstrate how I really wrote the code, which brings in functional programming, laziness, and asynchronous programming. Continue reading “Mock Free Example 4: Everything’s Better with Async”
In previous discussions about mock-free unit testing, I’ve shown techniques that I use to eliminate the hard-to-eliminate test doubles. I’ve skipped the simple techniques that I apply all the time. Time to fix that.
One technique eliminated about 90% of the test doubles in my code. It’s simple. It’s been around for a long time. Odds are you already do it but not frequently enough. It even has a name:
Extract Method. Continue reading “Easily Eliminate Most Mocks”
An overheard conversation at work got me thinking while I was headed home. I’ve now got to send some of those thoughts your way.
The one guy was arguing against agile on the basis that it “throws the baby out with the bathwater” with respect to design. Me made several statements. Some are true, some are partially true, and some are flat false. These statements are:
- There is still a role for design when trying to release quickly (true).
- Agile throws design out the window (mostly false).
- Agile only works with 5 people, in one room (false).
- Agile ships prototypes, not real code (false, but an easy misinterpretation from a true statement: agile teams always ship the simplest thing that could possibly give them the feedback they need).
Assuming the above represents his position, I would respond as follows. Continue reading “Agile vs Design”
In my character printer, at one point I had some code like this monstrosity. I know it’s a monster, because testing it
- Requires at least one test double (the
- Involves running a bunch of code not related to the unit test at hand.
Many people don’t think this code is so bad. They discuss various ways to test it, usually involving more mocks.
I’m going to show another way. Since it doesn’t require mocks and this is my blog, it’s a better way. Continue reading “Mock Free Example, Part 3: Fixing Untestable Code Sequences”
I recently posted an entry about replacing mocks with Simulators. That one used a Simulator from my running example code. Here’s another example, which may make the concept more clear.
This is a file system simulator. I’m building it out as a generic simulator, re-usable across projects. Right now, I’m using it Continue reading “Simulating the File System”
One of the common uses for mocks is to replace expensive or stateful components, such as file systems, networks, GUIs, and databases.
However, I also see a cluster of other problems that arise at interfaces with these types of components, especially when they are system-level services:
- Primitive obsession. Rarely are these APIs written as methods on an abstract object that return other abstractions. Instead, people pass around a lot of strings & things, which become arguments for static methods.
- State. Partly because there isn’t a place to put it, state tracking becomes a mess. For example, you want to ask a web service for something. Are you logged in? Do you have to do something if you aren’t?
- Lack of encapsulation. Those static methods end up everywhere. And often they end up with duplicate patterns everywhere (e.g., check for login before each call).
- The API does not feel natural to the application. It doesn’t follow the project’s idioms, and doesn’t just flow into place.
For this reason, I use an entirely different sort of test double: a system simulator. And often these simulators stop being test doubles Continue reading “Mock Free Example, part 2: Simulators”
Previously, I presented mocks as nuclear weapons. Unsurprisingly, commenters wanted examples. I exist to serve.
This series will discuss a partly-completed project that I have lying around. The project isn’t perfect. But it will serve to discuss some of the ideas. Since it’s only partly complete, some ideas visible in this stage that would likely become much more subtle with another few days’ work. Or so I hope.
It’s also a full project. The ideas blend into each other at the edges. I am not creating an example to demonstrate an idea; I’m showing how those ideas interact with each other in the wild. This will make the examples more difficult to follow. Sorry. I’ll do my level best to guide you to the areas that I find interesting (whether positive, negative, or simply unfinished).
Continue reading “Mock Free Example, Part 1: Project Intro”
I learned something very useful from Marty Nelson’s blog entry on the proficinecy levels of TDD. It was the first time that I saw a construction which included mock objects as a good thing and that also passed my sniff test. So, I hereby recant: Mocks are no more Evil than are nuclear bombs. I’ve learned to love them, as the tools of mass destruction that they are.
Actually, Continue reading “How I Learned to Stop Worrying and Love the Mock”
Recently, I’ve had a large number of discussions around the use of mocks for testing, probably because I keep saying that Mocks are Evil.
As a result, I’ve had to articulate how I design systems. Continue reading “Decoupled Design”
Primitive obsession is a problem because it results in duplicate code, poor cohesion, and poor coupling. What should be well-defined operations on some value become littered through the codebase and inextricably linked with other operations. Although this is commonly the result of using built-in language primitives where a more domain-related type would do, that’s not the only way to get there.
If you’ve got an object (class or struct, yours or from a library) with any of the following characteristics, you probably have a primitive obsesssion problem: Continue reading “Primitive Obsession Does Not Require Primitives”