Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Who says that you have to be able to mock C? Not every class should be mockable. In case described by OP, why would we want to mock cache anyways? In most cases singleton is used as a global state that can be easily accessed from all parts of the app without explicitly passing the state obj. We are dismissing a useful technique (singleton) based on requirement, that is not applicable to this technique.


> Who says that you have to be able to mock C? Not every class should be mockable. In case described by OP, why would we want to mock cache anyways?

Well it isn't really a unit test if you don't, is it? If you don't mock it then you're not only testing classes under unit tests, but also C's methods. And you're doing that not just in one place but in several different places in your testbase. The same methods. Over and over again.


I don't understand. If my unit test calls C.getX() over and over again, how is it bad?


C.getX() is going to be called by many different methods in many classes. This means that each time you unit test any of these methods, you're also testing C.getX() when you should only be testing what the method does.


+ sign and - sign are also called by unit tests many times, so you also repeatedly testing arithmetic operations "each time you unit test any of these methods, ... when you should only be testing what the method does".

Edit: I see what you say, but I think that effort we spend on decomposing app into perfectly isolated unit tests is far greater then the effort of identifying and troubleshooting where the less perfect test failed.


In my case a cache could be something remote, having any calls directly to that will slow down unit tests a lot, having one or two calls to it unit testing the cache implementation it self is OK, but having every method which makes use of it make those calls isn't going to work.

In reply to your original question, its not extremely bad if you can't unit test that class alone , but in this case you wouldn't be able to unit test anything which uses it either.


You want to mock cache so you can replace it with a trivial implementation that always contains precisely what the test expects it to contain.


Fill up the cache with mocks of the objects it needs to contain. 10 objects = 10 lines of code.

If you really want to have different cache implementation for testing purpose, use C as just an instance storage, and return reference not to self but to cache interface. Put a switch inside static C.getX() that returns IX. Inside of switch statement see if System.getProperty("isTest")=true and return XSimple (which implements IX), otherwise return XReal (which also implements IX). Few lines of code, transparent and debuggable.


"Fill up the cache with mocks of the objects it needs to contain. 10 objects = 10 lines of code."

But then I'm not testing the code that uses the cache, I'm testing the cache plus the code that uses the cache. Which is a valuable test but a separate one.

Regarding your proposed implementation, that sounds like basically what I proposed here:

https://news.ycombinator.com/item?id=7153126


Funny, I saw your code, but didn't put your name and code together:) There are many ways to mock a singleton. I am not against mocking it, but against over-complicating. Also, I think that we are taking unit testing a bit too far in trying to decompose the app into smallest pieces. Unit tests have specific goals, like verifying correctness of calculations or performance benchmarks. If test raises a red flag, it takes a few minutes to isolate the piece of code that is at fault.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: