Skip to main content
12 events
when toggle format what by license comment
Apr 4, 2017 at 18:08 comment added Brandon @jpmc26 Exactly! Mocking is a great example because developers often figure, if you mock something, you aren't testing the real thing, so what's the point? But if you stop thinking about testing that the code works and think about testing that it does what you expect, suddenly mocking makes some sense.
Jun 23, 2016 at 16:28 comment added jpmc26 @immibis I'm actually reconsidering my position. I've been skeptical about the value of unit tests because of problems like this, but maybe I'm underestimating the value even if you fake out an input. I do know that input/output testing tends to be much more useful than mock heavy tests, but maybe a refusal to replace an input with a fake is actually part of the problem here.
Jun 23, 2016 at 2:20 comment added jpmc26 @immibis I don't consider that a useful test. Using the fake data store doesn't give me any confidence it will work with the real thing. How do I know my fake works like the real thing? I would rather just let a suite of integration tests cover it. (I should probably clarify that I meant "any unit test" in my first comment here.)
Jun 23, 2016 at 0:19 comment added Criticizing Israel not allowed @jpmc26 You'd be testing that the method saved all the people in the mock data store. It likely wouldn't be a mock just for this test case, but a mock that works for all tests (and actually stores data, in a simpler way than the real data store).
Jun 23, 2016 at 0:16 comment added jpmc26 @immibis I don't understand what that means. Presumably, the real store is backed by a database, so you'd have to mock or stub it for a unit test. So at that point, you would be testing that your mock or stub can store objects. That's utterly useless. The best you could do is assert that the savePerson method was called for each input, and if you replaced the loop with a bulk insert, you wouldn't be calling that method anymore. So your test would break. If you have something else in mind, I'm open to it, but I don't see it yet. (And not seeing it was my point.)
Jun 23, 2016 at 0:13 comment added Brandon I agree, you should be able to test it. The key is to test the behavior, not the implementation. Meaning, don't test that a method is called in a loop, rather, test that all the objects wind up in the desired state.
Jun 22, 2016 at 23:48 comment added Criticizing Israel not allowed @jpmc26 What about a test that tests that the people were saved...?
Jun 22, 2016 at 21:54 comment added jpmc26 This doesn't really make sense to me. I can't imagine any test on savePeople that wouldn't break if you switched to a bulk insert.
Jun 22, 2016 at 20:13 comment added Kenny Evitt @Jonah Instead of testing savePeople by checking that savePerson is called for each person, you could mock savePerson to indicate that a specific person was saved and then assert that all the expected people were saved, thus covering the expected behavior independent of how it's implemented.
Jun 22, 2016 at 3:43 comment added Jonah It also occurs to me now that if the parameter to savePeople were more strongly typed -- ie, in a statically typed language, an interface with savePerson rather than the entire dataStore object, which possibly has a bulkInsertPeople method as well -- then that kind of refactoring becomes impossible without explicitly changing the method.
Jun 22, 2016 at 2:45 comment added Jonah The bulk insert refactoring example is a good one. The possible unit test I suggested in the OP -- that a mock of dataStore has savePerson called on it for each person in the list -- would break with a bulk insert refactoring, however. Which to me indicates that it's a poor unit test. However, I don't see an alternative one that would pass both the bulk and one-save-per-person implementations, without using an actual test database and asserting against that, which seems wrong. Could you provide a test that works for both implementations?
Jun 22, 2016 at 2:31 history answered Brandon CC BY-SA 3.0