Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: How to use Electrolyte IoC in tests? #38

Open
ssljivic opened this issue Feb 23, 2016 · 2 comments
Open

Question: How to use Electrolyte IoC in tests? #38

ssljivic opened this issue Feb 23, 2016 · 2 comments

Comments

@ssljivic
Copy link

Is there a way to somehow reset.reload container? That would be useful since, what I planned to do (in absence of a better idea) is to mock/modify/stub some of the injected dependencies for the purpose of a test. However, I want a clean state for the next test (usually I would reset container in beforeEach()).

If this is not the right way, can someone point me to the right direction? Electrolyte is great, but I could not find good example how to use it in tests and how to mock deps.

Another good thing would be the ability to manually add/override some component in the container - again for test mocking purposes (something similar to Angular's $provide...)

@xduseko
Copy link

xduseko commented May 16, 2016

You can create custom container for each test case.

const IoC = require('electrolyte');

describe('myModule', function() {
    let container;

    beforeEach(function() {
        container = new IoC.Container();
        container.use(IoC.dir('app/myContainerFolder'));
        myModule = container.create('myModule');
    });
});

... and override modules with mocks like

container.use(function(id) {
    if (id === 'myDep') {
        myDepMock['@literal'] = true;
        return myDepMock;
    }
});

...or create something like this...

@hoxxep
Copy link

hoxxep commented May 16, 2016

IoC.Container().use uses a hierarchy – the last .use(...) is the first one to be checked for an object. So while using a different container for each test is one option, adding extra .use(...)s during tests is another.

Assuming you have src/models which stores your UserModel, ExampleModel, etc., you can have test/mocks include mocks for ExampleModel; or if you need more refined control test/mocks/ExampleModel will be a directory containing only the ExampleModel mock.

This allows you to use the following in your main application:

const IoC = require('electrolyte');
const container = IoC.Container();
container.use(IoC.node_modules());
container.use(IoC.dir('src/models'));
container.use(IoC.dir('src/controllers'));
container.use(IoC.dir('src/routes'));
// ...

And then in your test set-up, you can either manually instantiate individual models with mocks (semi-ugly):

// IoC code above...
const ExampleController = require('src/controllers/ExampleModel');
const ExampleModelMock = require('test/mocks/ExampleModel');
let controller = new ExampleController(new ExampleModelMock(), IoC.create('UserModel'));

Or, add an extra .use(...) so that a mock called ExampleModel is resolved:

// IoC code above...
container.use(IoC.dir('test/mocks'));  // mocks must be named exactly the same as the original object
let controller = IoC.create('ExampleController');

Feature Request:

Although I would like to see some method that allows hot-swapping of different mocks. Perhaps something similar to

// in your tests bootstrap file:
container.use(IoC.dir('test/mocks'));  // mocks suffixed with 'Mock' such as 'ExampleModelMock'

// in a particular test:
let controller = IoC.create('ExampleController', {
  // override the `ExampleModel` with a mock
  'ExampleModel': IoC.create('ExampleModelMock')
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants