young-steveo / bottlejs

A powerful dependency injection micro container for JavaScript applications
MIT License
1.29k stars 67 forks source link

How to reset a bottle after unit tests? #113

Closed derekwsgray closed 6 years ago

derekwsgray commented 6 years ago

I'd like to clear the registered services on a bottle instance at the end of each unit test, but there doesn't seem to be such a method - hopefully I'm missing something?

jvitela commented 6 years ago

Have you tried resetProvidersNames ? https://github.com/young-steveo/bottlejs/blob/master/README.md#resetprovidersnames

Or why not just create an instance of Bottle per test?

derekwsgray commented 6 years ago

thanks, yes I did try resetProviders(), but it did not unregister the already constructed service from the previous test.

All my modules reference the bottle instance via require()ing the exported instance, not by function parameter, so I could not directly create a new bottle in each test. I ended up wrapping bottle in a manager that maintains the instance and adding a reset(), which archives the same effect of creating a new bottle per test. (calling it from mocha's after() hook.)

young-steveo commented 6 years ago

@derekwsgray resetProviders will unregister the provider and the service from the container by deleting the properties from the container.

These tests prove that this is the case, and show several examples of how the method is used and it's effects.

The purpose of this method is really only for unit tests. If you're finding that your service is sticking around after the provider is reset, you might be storing a reference to it outside of bottle; bottle can only delete the reference from the container.

derekwsgray commented 6 years ago

@young-steveo Thanks for the reply. I looked at those tests, and they don't actually exercise my case - so I believed it to not be working. But I must have been doing something else wrong in my code, because the following test passes. (Maybe you can add this to your suite - I perhaps missed it, but I didn't see a test that assigned a different implementation to the service after resetProviders():

const expect = require('chai').expect;
const Bottle = require('bottlejs');

describe('Testing bottleJS', function() {

    it('resetProviders allows re-registration', function () {
        const b = new Bottle();

        class FirstFake {
            value() { return 1; }
        }

        class SecondFake {
            value() { return 2; }
        }

        b.service('MyService', FirstFake);
        expect(b.container.MyService.value()).to.equal(1);

        b.resetProviders();
        b.service('MyService', SecondFake);
        expect(b.container.MyService.value()).to.equal(2);

    });

});