Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
react-magnetic-di
Advanced tools
A new take for dependency injection in React for your tests, storybooks and even experiments in production.
Dependency injection and component injection for testing purposes is not a new topic. Indeed, the ability to provide a custom implementation of a component/hook while testing or writing storybooks and examples it is extremely valuable.
A common pattern to solve this problem is injecting those "dependencies" in the component via props. However, that approach has a some of downsides, like leaking internal implementation details, mixing together injected dependencies with other props and introducing additional complexity when typing props.
react-magnetic-di
takes inspiration from decorators, and with a light touch of Babel magic and React Context allows you to optionally override such dependencies, with nearly-zero performane overhead (when not using it).
npm i react-magnetic-di
# or
yarn add react-magnetic-di
Edit your Babel config file (.babel.rc
/ babel.config.js
/ ...) and add:
// ... other stuff like presets
plugins: [
// ... other plugins
'react-magnetic-di/babel',
],
Given a component with complex UI interaction or data dependencies, like a Modal or an Apollo Query, we want to be able integration test it without necessarily test those other dependencies.
To achieve that, we mark such dependencies in the render
function of the class component:
import React, { Component } from 'react';
import { di } from 'react-magnetic-di';
import { Modal } from 'material-ui';
import { Query } from 'react-apollo';
class MyComponent extends Component {
render() {
// that's all is needed to "mark" these variables as injectable
di(Modal, Query);
return (
<Modal>
<Query>{({ data }) => data && 'Done!'}</Query>
</Modal>
);
}
}
Or on our functional component with hooks:
import React, { Component } from 'react';
import { di } from 'react-magnetic-di';
import { Modal } from 'material-ui';
import { useQuery } from 'react-apollo-hooks';
function MyComponent() {
// "mark" any type of function/class as injectable
di(Modal, useQuery);
const { data } = useQuery();
return <Modal>{data && 'Done!'}</Modal>;
}
In the unit/integration tests or storybooks we can create a mock implementation and wrap the component with DiProvider
to override any dependency:
import React from 'react';
import { DiProvider, di } from 'react-magnetic-di';
import { Modal } from 'material-ui';
import { useQuery } from 'react-apollo-hooks';
// mock() accepts the original implementation as first argument
// and the replacement implementation as second
const ModalOpen = di.mock(Modal, () => <div />);
const useQueryMock = di.mock(useQuery, () => ({ data: null }));
// test-enzyme.js
it('should render with enzyme', () => {
const container = mount(<MyComponent />, {
wrappingComponent: DiProvider,
wrappingComponentProps: { use: [ModalOpen, useQuery] },
});
expect(container).toMatchSnapshot();
});
// test-testing-library.js
it('should render with react-testing-library', () => {
const { container } = render(<MyComponent />, {
wrapper: (p) => <DiProvider use={[ModalOpen, useQuery]} {...p} />,
});
expect(container).toMatchSnapshot();
});
// story.js
storiesOf('Modal content', module).add('with text', () => (
<DiProvider use={[ModalOpen, useQuery]}>
<MyComponent />
</DiProvider>
));
In the example above we replace all Modal
and useQuery
dependencies across all components in the tree with the custom versions.
To test your changes you can run the examples (with npm run start
).
Also, make sure you run npm run preversion
before creating you PR so you will double check that linting, types and tests are fine.
FAQs
Context driven dependency injection
We found that react-magnetic-di demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.