Live data from Hacker News

Testing Without Mocks

jamesshore.com

11–20 of 51 posts

Re: Testing Without Mocks

#11
post #2

> The factory should create a “Nulled” instance that disables all external communication, but behaves normally in every other respect.... >...For example, calling LoginClient.createNull().getUserInfo(...) should return a default response without actually talking to the third-party login service. So... a mock.

I think the issue is "a mock" is a generalized term that implies different things depending on the usage. More junior developers think that it only means when you have an external entity that you have control over that "mocks" the external service that you don't (shameless plug, I built https://mockadillo.com for this). But yeah, these are obviously mocks and the article kind of doesn't make sense.

Re: Testing Without Mocks

#12
A "fake" (as opposed to a mock) is a pretty well understood concept.

Is there a difference between a fake and a "nullable"? As far as I can tell this is a pattern for merging your fakes and reals which seems cumbersome and error prone

Re: Testing Without Mocks

#13
This seems close to what I do, except I dependency inject the alternate implementations rather than modifying production ones to do the job, which seems weird. Plus I may want more than one implementation.

At least at the scale of code I've been working with, it has been excellent. People keep threatening me with dire promises of how this or that testing practice will result in fragile, highly-coupled tests, and all I can say in response is that in 10+ years of continuously writing tests you'd think it would have happened to me by now. Instead I tend to make very reasonable changes to my tests as I go, and the only times I've ever ended up rewriting them top to bottom is when the underlying code under test changed so much that it was inevitable anyhow.

I tend to have a test module that sets up an entire test environment with all the stub implementations, which works fairly well in that middle ground between full integration and unit tests.

Re: Testing Without Mocks

#14
post #4

If you make all your code as pure function, then testing is easy. First thing to do: Stop using class. Ask yourself first: Should i use a class here and there ? Wait, i miss something here: Writing pure functions is hard ?

Alright, so you get numbers from a json file in a ftp servers, you use scipy.newton to perform root finding on it, but needs the number of steps to be outputted as well (which newton() doesn't return), and you will save the result in a postgres table. All this should be send to a task queue, triggered by a call to your REST API. Good luck with purity.

> Good luck with purity.

Most of your counter example needs integration tests to test properly anyhow - not really a good point.

If you can give up encapsulation (which IMO isn't actually that useful in practice) and in return, your program becomes 95% functional, that seems like a really good tradeoff.

Re: Testing Without Mocks

#15
post #2

> The factory should create a “Nulled” instance that disables all external communication, but behaves normally in every other respect.... >...For example, calling LoginClient.createNull().getUserInfo(...) should return a default response without actually talking to the third-party login service. So... a mock.

I’m not sure I manage to follow the author correctly, but to me it seems that by “mock” they strictly refer to external mocking libraries, in the sense of JS’s `testdouble` [1] or Java’s `Mockito` [2]. The static fake object as returned by `LoginClient.createNull().getUserInfo(...)` appears to be a “Nullable” for them.

[1] https://www.npmjs.com/package/testdouble

[2] https://site.mockito.org/

Re: Testing Without Mocks

#16

I get that in other software stacks you might want to avoid mocks and stubs due to friction, but in JavaScript what's the big deal? Mocks are easy– just do it.

Mocks, especially spies, couple your tests to the implementation of the system under test. This leads to a very common code smell in tests: Fragile Test. The problem is that instead of being concerned only with behaviour, the test are knowing something about the implementation details of the SUT (dependencies are an implementation detail that consumers ought to be unaware of).

One of the major benefits of automated tests is that they can provide a safety net that allows you to refactor with less risk of breaking behaviour. If tests get in your way of refactoring, because changing the implementation details of your SUT cause your tests to start failing, then the tests have failed at being a tool to facilitate refactoring.

Re: Testing Without Mocks

#17
post #2

> The factory should create a “Nulled” instance that disables all external communication, but behaves normally in every other respect.... >...For example, calling LoginClient.createNull().getUserInfo(...) should return a default response without actually talking to the third-party login service. So... a mock.

No that’s not a mock that’s a stub. See this book from software engineers at Google, it talks about various test doubles: https://abseil.io/resources/swe-book/html/ch13.html

They use the word mock several times to explain stubbing. I think they mean stubbing is a type of mocking not an independent approach. They even use a mocking library to create stubs in the Google article.

Re: Testing Without Mocks

#18
post #2

> The factory should create a “Nulled” instance that disables all external communication, but behaves normally in every other respect.... >...For example, calling LoginClient.createNull().getUserInfo(...) should return a default response without actually talking to the third-party login service. So... a mock.

I think we call those "fakes", and reserve mocks for those tests that count the number of times a function was called, yielding "change detector tests".

Personally, I find it best to not be too concerned about the terminology, and make sure your test doubles get the data that the code under test needs to the place that needs it. The more real code you can involve in integration tests, the better; only look at replacing real code with test doubles if there is a performance or reliability downside. Databases have never hit that performance/reliability downside for me; network services do.

Re: Testing Without Mocks

#19
post #2

> The factory should create a “Nulled” instance that disables all external communication, but behaves normally in every other respect.... >...For example, calling LoginClient.createNull().getUserInfo(...) should return a default response without actually talking to the third-party login service. So... a mock.

No that’s not a mock that’s a stub. See this book from software engineers at Google, it talks about various test doubles: https://abseil.io/resources/swe-book/html/ch13.html

Also https://www.martinfowler.com/articles/mocksArentStubs.html

Re: Testing Without Mocks

#20

I get that in other software stacks you might want to avoid mocks and stubs due to friction, but in JavaScript what's the big deal? Mocks are easy– just do it.

Mocks and stubs provide lower test fidelity than the real thing. Also makes your tests more brittle as you need to update them whenever the real implementation changes.

Of course test the real thing if you can. The introduction of mocks and stubs to the conversation to me has already implied that is not possible.
Post reply on HN