I am working on a React application and I want to test one module, let's call it B, that depends on another module, let's call it A.
The scenario could be something like this:
moduleA.js
export function helperFn() {
return { prop1: 10, prop2: 20 };
}
moduleB.js
import React from 'react';
import { helperFn } from '../moduleA';
export class CustomComp extends React.Component {
render() {
const helperObj = helperFn();
return (
<div>{helperObj.prop1}</div>
);
}
}
The core libraries to test my components are Jest and Enzyme. My goal here is to test module B, but I want to test it in isolation and so I want to mock the dependency on moduleA.js.
I know one way would be to inject the helperFn as a prop instead of importing it so during the test I can inject a mock function, but there are modules quite big on this app that have a few dependencies each of them.
Researching a bit I found it is posible to mock a dependecy using Jest, but I tried many things with no success. I tried approaches from this question, also from this post and I have no luck. I also read the Manual Mocks and Mock Functions guides from Jest docs, but I think they are pretty confusing.
I could make it work (i.e. I could mock moduleA.js dependency) using the approach on this post, but I had another problem then. It worked just fine to test moduleB.js, but when I went ahead and test moduleA.js, I had to import moduleA.js in moduleA.test.js and I got the mock while I wanted the real module.
So, I need help to understand how I can mock dependency A in moduleB test file.
I hope I was clear if not let me know and I will add the clarifications you might need.
Thanks in advance !
Indeed you can use jest to mock your dependency. There is some configuration you need to set in order to make it work with import. E.g. configuring babel-jest.
If you already have that configuration then you can mock it like so.
import React from 'react';
import { shallow } from 'enzyme';
import { helperFn } from '../moduleA';
jest.mock('../moduleA');
describe("CustomComp", () => {
it("should render component", () => {
helperFn.mockReturnValueOnce({
prop1: "dummy"
});
const component = shallow(<CustomComp />);
});
You can see a working example here.
I'm using Vue2 and trying to write tests for a Vue component. The Vue component uses a lot of other components that aren't really needed to test.
So for that reason, I created a mock for importing other components like below
jest.mock('#/core/components/UserInput.vue', () => ({
exec: jest.fn(),
}));
Related
I am doing a web-based e-commerce site. Now I need to perform unit testing. Are there any tools required for unit testing?
There are a couple of testing frameworks and libraries for this.
The ones I use are Jest and React Testing Library
There is a curve for the setup but if you are using create-react-app it's already done.
As for the question 'how'. It's dependent of the code because some components just render props and the testing itself is just checking that the props are rendered a certain way.
Some other components have data fetching, hooks and dependencies that need mocking. Until you learn the quirks of both libraries I would advise testing simpler components first. I leave one example
========== index.js ============
import React from 'react'
export default function MyComponent(){
return <div>test</div>
}
=========== index.test.js =============
import React from 'react'
import { render, screen } from '#testing-library/react'
import '#testing-library/jest-dom'
import MyComponent from '.'
test("should render 'test'", () => {
render(<MyComponent />)
expect(screen.queryByText("test")).toBeInTheDocument()
})
I've been having an odd issue with Jest/Enzyme testing on my react typescript app. For some reason it gives a syntax error even though this is following the official documentation, as well as input from several articles.
The Code:
import React from 'react';
import NavbarTop from "../components/navbar";
import { shallow } from 'enzyme';
describe('NavbarTop', () => {
it('renders correctly', () => {
const wrapper = shallow(<NavbarTop />);
expect(wrapper).toMatchSnapshot();
// On the first run of this test, Jest will generate a snapshot file automatically.
});
});
The folder structure. I have a named class and then an index with a default export.
The error log.
Do you have JSX configured for Jest? Looks like you don't have support for JSX in Jest, which probably means this is a configuration issue. Have a look at configuring babel to support JSX in Jest.
Make sure you read this tutorial
I've created a very basic functional component in React (using Typescript).
However when I go to test it - I keep getting received {} when I ask it gather the divs:
So the component looks like:
export const TestComponent: React.FC<FakeInt> = () => {
return (
<div>ARE YOU WORKING
<div>Checking here</div>
</div>
)
};
along with
interface FakeInt {}
And the test:
it('It does something', () => {
let wrapper = shallow(<TestComponent />);
expect(wrapper.find("div")).toEqual("")
});
(I've just put equal to "" - as I'd expect to see something received/just want to confirm its actually finding those divs)
If I had console.log(wrapper.debug()); I actually see the wrapper's content which is strange.
The version of Jest I'm using came with my React app.
And another piece of info. expect(wrapper).toMatchSnapshot(); creates a snapshot file which also contains an empty object {}
Any ideas what's up here/why this wouldn't work?
Thanks.
please provide the version of enzyme you are using, also for react you should use enzyme-adapter-react-16 (or what ever version of react you are using)
in the test:
import { shallow, configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({ adapter: new Adapter() })
than it should work
I've got a (private) npm module that exports several React components. The module is bundled by Webpack and in the generated bundle a reference to one of the components (say Warning) looks like this:
t.d(n,"Warning",function(){return ge})
Then I've got a React project importing this module:
import { Warning } from 'my-custom-module';
...
render() {
return (
<Warning>Lorem ipsum</Warning>
);
}
This all works OK, but when I create a Jest snapshot of the component above, I expect the snapshot to look like
<Warning>Lorem ipsum</Warning>
but it looks like:
<ge>Lorem ipsum</ge>
For some reason Jest takes the minified identifier instead of the exported name of the component. How can I see the component name in the Jest snapshot? I'm unsure if I do need to adjust my Webpack config or the Jest setup...
Since you are referring the uglified version of the 'my-custom-module' it will try to render to the uglified names. However, I assume what you actually you need is to shallowly render your component.
You can use the Enzyme libraries's shallow renderer for this.
//MyAwesomeComponent.js
import { Warning } from 'my-custom-module';
export default class MyAwesomeComponent extends Component{
render(){
return (<Warning>Lorem ipsum</Warning>);
}
}
//MyAwesomeComponent.test.js
import { shallow } from 'enzyme';
import MyAwesomeComponent from './MyAwesomeComponent';
it('renders <MyAwesomeComponent />', () => {
const shallowMyComponent = shallow(<MyComponent />);
expect(shallowMyComponent).toMatchSnapshot()
});
This should show your snapshot as Warning without going a level deeper.
I'm using a __mocks__ folder to mock a node_module. Nice.
Example to one of the mocks, that mock 'react-relay': https://gist.github.com/robrichard/ad838e599d828a89978f54faaa2070a8
The file is located as such __mocks__/relay-react.js,
the the mock with be used in my test when jest.mock('react-relay) is executed in the testfile.
However, I have many repos that need that same mock. Is it possible to put the mock in a node_module, so to streamline my tests and do not have to copy/paste the mock everywhere?
This is the best solution so far (as described here: https://github.com/facebook/jest/issues/2726#issuecomment-283100333):
testutils.js
import React, { Component } from 'react';
exports.mockRelay = {
createFragmentContainer: Component => props => <Component {...props} />,
...
// all the named imports you want to mock
};
then in the testfile call
jest.mock('react-relay', () => require('util/testutils').mockRelay)