CSS-only tabs are a fun topic, and :target is a delightfully elegant declarative approach, except for the bit where it doesn’t work. The…
How can you use client-side libraries like Leaflet, on the server?
You’ve written an application deployed using Dokku, and you’ve got it all up and running and great. You’ve heard a lot about why HTTPS is…
The problem is that with
sinon.stub(Lookup, 'getService') you're mutating the insides of the Lookup variable you're holding in your tests, and then getting the method from that variable. In your Lookup module though the function is just finding
getService directly from its local scope. Externally I don't think there's any way you can mess with that scope, so there's no easy magic fix for this I'm afraid.
Generally, you usually can't nicely mock parts of a single module in a test. You need to restructure this a bit, and there's a few options:
Test them totally separately. Change getServiceWithRetry into a generic
retry method, e.g. so you can call it like
retry(nTimes, getService, "serviceName") or
retry(() => getService("serviceName"), nTimes)). If it's practical to do this (i.e. if it's not too tied it to
getService) then you can then easily test this on its own:
var myStub = sinon.stub(); myStub.onCall(0).throw("fail once"); myStub.onCall(0).throw("fail twice"); myStub.returns(true); // then return happily expect(retry(myStub, 1)).to.throw("fail twice"); // gives up after one retry expect(retry(myStub, 5)).to.return(true); // keeps going to success
If elsewhere you want to be able to just call a single getServiceWithRetry, you can build one easily:
var getServiceWithRetry = (arg, triesLeft) => retry(getService, tries)
Give up, and test them together. This means stubbing out the things that
getService depends on, rather than stubbing it directly. It depends on what level of granularity you want from your tests, but if this code is simple and you can test more coarsely, this might be an easy option.
You might want to do this even if you've separately them anyway, to get a unit and integration test for extra coverage. This is doubly true if there is some more complicated interactions going on between them.
Maybe not relevant in what this case, from what I can see, but in other cases sort-of like put the method-under-test (getServiceWithRetry) in a class, and use dependency injection. You'd create a class that takes the dependency (the getService method) in its constructor, stores it internally, and uses it later when you call methods on resulting object. In your production code something else will have to glue those together correctly, and then in your tests you can pass in a stub instead.
Also overkill for this case I expect, but you could pull
getService into a totally separate module that Lookup imports, and use something like Rewire to swap it out for a different module during testing.
This is quite similar to the dependency injection option really, and makes your production code simpler, but at the cost of making your testing code more complicated and magical.