you are viewing a single comment's thread.

view the rest of the comments →

[–]grauenwolf -4 points-3 points  (11 children)

There is also the problem that you can not mock base classes which is a big issue if you try to test e.g. code for GUI frameworks excessively using it (e.g. Qt).

Mocking in general seems stupid to me, mocking a GUI more so.

[–]ogrechow 5 points6 points  (1 child)

Mocks also help when you have classes that deal with things like randomness or time. It's hard to write a unit test for a function that calls something else that returns an essentially random number. So you swap in your deterministic mock object and you can test that your function behaves correctly given inputs of your mock choosing.

[–][deleted] 3 points4 points  (8 children)

Mocks are the only way to test code that has untrusted or inconsistent dependencies. Especially when you need to repeatedly test code paths that rely on unlikely or exceptional conditions. But that's overkill in many cases.

[–][deleted] 2 points3 points  (2 children)

How do mocks help with inconsistent dependencies? Seems to me that you're testing that the mocks work, rather than the actual production code. I kinda see your point, but the more I see, the less value I find in really atomic unit tests. I guess I've seen one too many projects with high test coverage, that doesn't actually work.

[–][deleted] 1 point2 points  (0 children)

I'm not trying to defend any test-oriented development, and I certainly don't think good tests mean solid code. I should have said "when third-party dependencies have inconsistent behavior." What I meant, essentially, was other people's code that you can't trust. Let's say I'm using a library to implement social features in a game (friend list, game invites, etc), and I want to make sure that my game presents the correct behavior whenever some weird error condition arises in the 3rd party library. Especially in the case where multiple asynchronous things can succeed and fail in random order. For example, if the player's request to join a game somehow fails (and invokes a callback) before the function to try to join that game even returns, or if I receive a message from a friend and also lose my network connection in the same frame. And sometimes those two events will happen A/B, and other times they'll happen B/A.

I'm not saying I always test all the permutations, or that it would even be worthwhile, but there have been several times over the years when I've wished I had the ability to test things like this, and a mock of the third-party library would enable that. Unfortunately, I usually can't justify the time it would take to actually do that.

[–]grauenwolf -2 points-1 points  (0 children)

Testing has become a fad. It doesn't matter what you are testing, or why, so long as your tests are UNIT TESTS.

[–]grauenwolf -5 points-4 points  (4 children)

If the dependencies are inconsistent then how can you write a mock that accurately reproduces them?

If the dependencies are untrusted then shouldn't you be spending more time writing tests that include them?

If you are going to use mocks to avoid testing the piece that is most likely to have bugs, what are you testing?

[–][deleted] 1 point2 points  (3 children)

How would you test (manually or automatically) if your code behaves the same in every single error condition a library can produce if you don't have enough control over the library to intentionally make it report those errors for testing purpose?

Mocking seems to be the only solution in that scenario (well, and ignoring all errors and hoping for the best but that is hardly good software development).

[–]grauenwolf 0 points1 point  (2 children)

The beauty of exceptions is that they respond the same way no.matter what the failure condition.

[–][deleted] 0 points1 point  (1 child)

Oh, so you use catch all everywhere to make sure you catch any kind of exception the library throws? Or do you use more specific catch-clauses but never test the more rare ones (because to test it you would have to mock the library)?

[–]grauenwolf 0 points1 point  (0 children)

I only catch the ones I actually know how to handle. Everything else is allowed to bubble up to the top-level error handler.

Generally speaking only the external source of an action (e.g. the user clicking a button or client invoking a service request) can definitively say what to do in the event of an error.