React testning library Undefined property in component - reactjs

I dont understand why the property of the component is breaking the test?
Do i have to pass the component the properties? Even if i do pass the props i still get the same error.
I dont want to test implementation details.
Thanks in advance!
Here is my code:
it("render correctly", () => {
const { getByTestId } = render(<CalendarAvailability />);
const date = getByTestId("date");
expect(date).toBeInTheDocument();
})
The Component:
import {Availability, AvailableDate, Status, AvailableDateContainer} from './CalendarAvailability.css'
function CalendarAvailability({unitData}) {
return(
<Availability data-testid="calendar-availability-component">
<AvailableDateContainer>
<AvailableDate data-testid="date">{unitData.date}</AvailableDate>
</AvailableDateContainer>
</Availability>
)
}
export default CalendarAvailability;
The failing test:
● <CalendarAvailability /> › renders without breaking
TypeError: Cannot read property 'date' of undefined
5 | <Availability data-testid="calendar-availability-component">
6 | <AvailableDateContainer>
> 7 | <AvailableDate data-testid="date">{unitData.date}</AvailableDate>
| ^
8 | </AvailableDateContainer>
9 | </Availability>
I dont want to test the props only the rendring of the div?

Related

write unit test for event handlers that updates some state in react using jest and enzyme

I am trying to write some unit tests for the event handlers that I wrote inside my component. I would like to write tests for the states updates inside that event handlers.
For example I have the following function that are called onMouseDown inside the component. How can I write some tests about that.
const [visible, setVisibility ] = useState(false);
const onSelection = () => {
setVisibility(!visible)
};
<div onMouseDown ={()=> onSelection(items)}>Click</div>
{visible && <div>simple text</div>}
Can anybody guide me through there. Thanks in advance
Suppose the component like this:
index.tsx:
import React, { useState } from 'react';
export default function Example() {
const [visible, setVisibility] = useState(false);
const onSelection = () => {
setVisibility(!visible);
};
return (
<div>
<div onMouseDown={() => onSelection()}>Click</div>
{visible && <div>simple text</div>}
</div>
);
}
We test the behavior of the component from the user's perspective.
We should test: What is the component rendering before triggering the mousedown event and what is rendered after the visible state changes.
index.test.tsx
import { shallow } from 'enzyme';
import React from 'react';
import Example from './';
describe('70577146', () => {
test('should pass', () => {
const wrapper = shallow(<Example />);
const button = wrapper.find('div[children="Click"]');
expect(wrapper.find('div[children="simple text"]').exists()).toBeFalsy();
button.simulate('mousedown');
expect(wrapper.find('div[children="simple text"]').exists()).toBeTruthy();
});
});
Test result:
PASS examples/70577146/index.test.tsx (11.966 s)
70577146
✓ should pass (11 ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.tsx | 100 | 100 | 100 | 100 |
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 13.599 s, estimated 14 s

angular-mocks giving me a module error when testing a component

I'm receiving the following error when trying to test a component with angularJS. This component is part of a library I've created with this language and uses Jest instead of Jasmine.
TypeError: angular_1.default.mock.module is not a function
6 | describe('Badge', () => {
7 | beforeEach(() => {
> 8 | angular.mock.module(['myApp.components.quoteCard']);
| ^
9 | });
10 | it('renders badge', () => {
11 | render(`
This is the test code following the specifities:
import angular from 'angular';
import 'angular-mocks';
import { render, screen } from 'angularjs-testing-library';
import './quote-card';
describe('Badge', () => {
beforeEach(() => {
angular.mock.module(['myApp.components.quoteCard']);
});
it('renders badge', () => {
render(`
<quote-card-component
content="content"
author="author"
></quote-card-component>
`);
expect(screen.getByText(`content`)).toBeInTheDocument();
});
});
If someone knows how to solve this, it would be great. Thanks folks!
Angular mocks works only with Jasmine or Mocha. Theres a strict condition inside the library. So you need to setup a global variable before running your tests.
For example
global.mocha = true;

Jest, Enzyme test failing on window variable undefined

I'm trying to create a window object to pass to my tests that includes a window variable. The test looks like:
const baseProps = {};
Enzyme.configure({ adapter: new Adapter() });
const baseWrapper = shallow(
<DivisionOrderIndex {...baseProps} />,
);
describe('<DivisionOrderIndex />', () => {
test('renders the MsDataGridServer', () => {
expect(baseWrapper.find(MsDataGridBulkDelete))
.toHaveLength(1);
});
The error message I receive is:
TypeError: Cannot read property 'read_only' of undefined
300 | </TitleButton>
301 | </div>
> 302 | {!window.jsdata.read_only && (
| ^
303 | <div id="page-buttons">
304 | Create New
305 | </div>
I've tried adding that data to my window object like so:
describe('<DivisionOrderIndex />', () => {
Object.defineProperty(window, 'jsdata', {
read_only: false,
});
test('renders the MsDataGridServer', () => {
expect(baseWrapper.find(MsDataGridBulkDelete))
.toHaveLength(1);
});
But I continue to get the same error. Is this the correct way to pass both the window object or the variables? Any input would be appreciated.
That's not how you add a property to an object. What you're doing here is adding a descriptor property that describes your object, there are only a few of them that you can set here e.g. writable, configurable etc.
You need to mock window object in the setupTests.js file like this:
window.jsdata = {
read_only: false
}

React Native Jest Syntax Error: Unterminated Regular Expression

I'm getting this strange syntax error whilst running a simple test for a Todo demo I'm writing. I have added the code and test in the same file so that you can see what's going on.
Any help will be greatly appreciated.
import { Text } from 'react-native';
import React from 'react';
import { shallow } from 'enzyme';
const TodoItem = () => {
return(
<Text>{Hello}</Text>
);
};
export default TodoItem;
describe('<TodoItem', () => {
it('should update uncompleted task to complete when pressed', () => {
const wrapper = shallow(<TodoItem />)
});
});
Test Result
Run: jest
FAIL __tests__/components/TodoItem.spec.tsx
● Test suite failed to run
SyntaxError: /Users/jonesagyemang/Projects/side/Todoist/__tests__/components/TodoItem.spec.tsx: Unterminated regular expression (7:19)
5 | const TodoItem = () => {
6 | return(
> 7 | <Text>{Hello}</Text>
| ^
8 | );
9 | };
10 |
at Object.raise (../../../../../usr/local/lib/node_modules/jest/node_modules/#babel/parser/lib/index.js:6322:17)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.2s
Ran all test suites related to changed files.
Watch Usage: Press w to show more.
I'm assuming it's a text that you want to display with Text component. Try removing the {} for the Hello since it isn't a variable or a function in your code.
const TodoItem = () => {
return(
<Text>Hello</Text>
);
};

enzyme mount component has error in i18n

I use i18n in my component and wrapped in I18nextProvider like this:
const wrapper = shallow(
<I18nextProvider i18n={mockI18n}>
<Component initState={initData} />
</I18nextProvider>
);
The mockI18n is:
const mockI18n = {
t(k) {
return k;
},
on() {
},
getFixedT(k) {
return (k) => k;
},
loadNamespaces(arg) {
return (arg) => arg;
}
};
This works fine when I use shallow. However, I want to test a onChange function, so I need to find the element and simulate click event in a nested sub component. The shallow is not able to find the element, so I want to try out mount, but wen I use mount it gives me error:
ReferenceError: t is not defined
16 | name="user_id"
> 17 | label={t('User ID')}
18 | type="text"
19 | value={this.state.user_id}
What should I do to apply i18n to sub component? Or how to test this.props.onChange when use shallow?
I think inside the component you need to get the t function inside the component that uses the translation.
const { t } = props;
...
Only then you can call the t function.
label={t('User ID')}
https://react.i18next.com/getting-started.html

Resources