4 ms·
Ideally mocks and stubs should be used only when the thing you're mocking/stubbing is either slow or complex. In general, just call the real thing and don't wo
by glenjamin 14y ago
Ideally mocks and stubs should be used only when the thing you're mocking/stubbing is either slow or complex.
In general, just call the real thing and don't worry about it. Otherwise you'll expend loads of time and energy setting up fakes to test relatively simple code.
- jarrett 14y agoAgreed, and furthermore: Mocks don't verify that you're calling external code correctly. Suppose you think API method does X, but it actually does Y. You won't detect that with mocks. Maybe you have integration tests (i.e. tests of the entire system working in concert) to account for that, but I say, why not catch these things at every chance you get?
- LargeWu 14y ago>why not catch these things at every chance you get? Because it's expensive. It takes time to write and maintain those tests. It takes time to run those tests. If you want to verify that API method works as assumed (and I assume you are talking about an API on an external system, but ultimately it doesn't really matter) then write a test specifically testing that API method. Testing that method B also works while testing method A is, in my experience, the number one culprit of people writing bad tests. These tests are harder to set up, take longer to run, and are more prone to promoting brittle test code. Test everything that's important to test, and nothing more. This is true whether you are talking about your entire system, or a single method.
- glenjamin 14y agoI agree, the thing I was trying to warn about is meticulously mocking out everything you possibly can to test every single method/class in complete isolation from the rest of the system. It's very tempting to start doing this when you get into heavy unit testing, but I find in practice this adds more cost than value. As an example, lets take some python code I just made up which formats some input into a message, throws the message onto the queue, and returns the message ID. class DelayedJob(object): def __init__(self, queue): self.queue = queue def add_job(self, task, params, priority=1): m = JSONMessage({ task: task, params: params, }) self.queue.add(m, priority) return m.getID() It's pretty clear that the queue service needs to be mocked out, as you don't want to be talking to a real queue for a unit test (you'll probably want some sort of acceptance/integration test to cover this somewhere). However, I have in the past been tempted to make the JSONMessage class injectable, and then inject a mock with a stubbed implementation of getID - I've often seen other people do this as well. The code required to set-up such a fake would be fairly verbose and add little in the way of extra clarity to the test. Since the class is fast and simple (in this scenario it's just a container) then I'd just leave the concrete class in use.