I'm new in writing test case, trying to write for onChange event while uploading File in react. I've gone through some of the links but still couldn't find any answer to it.
Here is the code:
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div
className={`dropzone ${isDragging ? "dragging" : ""}`}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
onDragOver={handleDragOver}
onDrop={handleDrop}
>
<input
type="file"
id="input-file-upload"
className="inputFile"
data-testid="input-field"
onChange={handleFileInputChange}
/>
<label htmlFor="input-file-upload" id="label-file-upload">
<div>
<button
style={{ display: "block", margin: "auto" }}
onClick={handleButtonClick}
>
Add File
</button>
{selectedFile ? (
<p>Selected File: {selectedFile.name}</p>
) : (
<p>Drag and drop files</p>
)}
</div>
</label>
</div>
</div>
OnChange event:
const handleFileInputChange = (e) => {
const file = e.target.files[0];
setSelectedFile(file);
console.log(file);
};
Test case:
test.only("input field onChange", () => {
render(<App />);
expect(screen.getByTestId("input-field")).toBeInTheDocument();
});
Unable to cover onChange event, not sure how to do it (here, input element field is not visible). Here is the link for full code (https://codesandbox.io/s/upbeat-glade-x9h48c?file=/src/tests/index.test.tsx:117-246). Could anyone please help me in this? Thanks in advance!
You can use the upload()
API of user-event
to upload files and trigger the onChange
event handler of <input type='file' />
React built-in component.
index.jsx
:
import React, { useState } from 'react';
export function App() {
const [isDragging, setIsDragging] = useState(false);
const [selectedFile, setSelectedFile] = useState(null);
const handleDragEnter = (e) => {
e.preventDefault();
setIsDragging(true);
};
const handleDragLeave = (e) => {
e.preventDefault();
setIsDragging(false);
};
const handleDragOver = (e) => {
e.preventDefault();
};
const handleDrop = (e) => {
e.preventDefault();
setIsDragging(false);
const file = e.dataTransfer.files[0];
setSelectedFile(file);
console.log(file);
};
const handleFileInputChange = (e) => {
const file = e.target.files[0];
setSelectedFile(file);
};
const handleButtonClick = () => {
document.getElementById('input-file-upload').click();
};
return (
<div className='App'>
<div
className={`dropzone ${isDragging ? 'dragging' : ''}`}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
onDragOver={handleDragOver}
onDrop={handleDrop}
>
<input
type='file'
id='input-file-upload'
className='inputFile'
data-testid='input-field'
onChange={handleFileInputChange}
/>
<label htmlFor='input-file-upload' id='label-file-upload'>
<div>
<button style={{ display: 'block', margin: 'auto' }} onClick={handleButtonClick}>
Add File
</button>
{selectedFile ? <p>Selected File: {selectedFile.name}</p> : <p>Drag and drop files</p>}
</div>
</label>
</div>
</div>
);
}
index.test.jsx
:
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { App } from './index';
test.only('input field onChange', async () => {
render(<App />);
const input = screen.getByTestId('input-field');
expect(input).toBeInTheDocument();
const file = new File(['hello'], 'hello.png', { type: 'image/png' });
await userEvent.upload(input, file);
expect(screen.getByText('Selected File: hello.png')).toBeInTheDocument();
});
Test result:
PASS stackoverflow/76759159/index.test.jsx (9.761 s)
✓ input field onChange (84 ms)
-----------|---------|----------|---------|---------|-----------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-----------------------
All files | 54.17 | 75 | 28.57 | 54.17 |
index.jsx | 54.17 | 75 | 28.57 | 54.17 | 8-9,13-14,18,22-27,36
-----------|---------|----------|---------|---------|-----------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 10.089 s
package versions:
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^14.4.3",
"@testing-library/jest-dom": "^5.16.5",
"jest": "^26.6.3",
"react": "^16.14.0",
"react-dom": "^16.14.0",