OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

vitest react write-excel-file: how to test FileSaver.saveAs (download file)

  • Thread starter Thread starter Stefan Krüger s-light
  • Start date Start date
S

Stefan Krüger s-light

Guest
i try to write a test for my react component that displays a button, and when clicked generates a xlsx file and offers to download. for this i use these tools:


for this i found How to use Jest to test file download?

and tried to translate this jest example to my vitest enviroment:

Code:
// ...
import FileSaver from "file-saver";
vi.mock("file-saver", () => {
  return {
    default: { saveAs: vi.fn() },
    saveAs: vi.fn(),
  };
});

global.Blob = function (content, options) {
  return { content, options };
};

// ...

but i get

Code:
FAIL  src/MyExample/index.test.jsx > MyExample > check template download AssertionError: 
expected "spy" to be called at least once  ❯ src/MyExample/index.test.jsx:29:30
     27|     await user.click(btn);
     28| 
     29|     expect(FileSaver.saveAs).toHaveBeenCalled();
       |                              ^
     30|     expect(FileSaver.saveAs).toHaveBeenCalledWith(
     31|       {

i have no idea if my basic concept can work at all..
i thought that with this mock i replace the global FileSaver lib..
but it seems this is not the case..
i am a bit lost how to track this done and would like to learn too..
i already extracted the saveAs part from the write-excel-file library to my own component so that it is a bit easier for me to understand what is going on..
without success currently.

What is the correct way / best practice to setup such a test case?

my full example at codesandbox.io

my component looks like this

Code:
import * as React from "react";
import { Button } from "@mui/material";

import writeXlsxFile from "write-excel-file";

export const MyExample = () => {
    const exampleData = [
        {
            forename: "Diana",
            surname: "Umlauft",
            email: "[email protected]",
        },
        {
            forename: "Jana",
            surname: "Friedmann",
            email: "[email protected]",
        },
    ];

    const columnsDefinition = [
        {
            column: "forename",
            value: (person) => person.forename,
            type: String,
            width: 15,
        },
        {
            column: "surname",
            value: (person) => person.surname,
            type: String,
            width: 15,
        },
        {
            column: "email",
            value: (person) => person.email,
            type: String,
            width: 30,
        },
    ];

    async function handleDownloadExampleXLSX(event) {
        console.log("handleDownloadExampleXLSX");
        try {
            const xlsxBlob = await writeXlsxFile(exampleData, {
                schema: columnsDefinition,
                // https://gitlab.com/catamphetamine/write-excel-file#browser
                // when no fileName is given results in blob
                fileName: `testFile.xlsx`,
            });
            //console.log("xlsxBlob", xlsxBlob);
            // saveAs(xlsxBlob, `testFile.xlsx`);
        } catch (error) {
            console.log(error);
        }
    }

    return (
        <>
            <Button onClick={handleDownloadExampleXLSX}>
                Download Example
            </Button>
        </>
    );
};

export default MyExample;

and my test file

Code:
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import MyExample from ".";

// based on https://stackoverflow.com/questions/44686077/how-to-use-jest-to-test-file-download
import FileSaver from "file-saver";
vi.mock("file-saver", () => {
  return {
    default: { saveAs: vi.fn() },
    saveAs: vi.fn(),
  };
});

global.Blob = function (content, options) {
  return { content, options };
};

describe("MyExample", () => {
  test("check template download", async () => {
    const user = userEvent.setup();
    const { container } = render(<MyExample />);
    const btn = screen.getByText(/Download/i, {
      selector: "button",
    });
    expect(btn).toBeInTheDocument();
    await user.click(btn);

    expect(FileSaver.saveAs).toHaveBeenCalled();
    expect(FileSaver.saveAs).toHaveBeenCalledWith(
      {
        size: 5531,
        options: {
          type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        },
      },
      "testFile.xlsx",
    );
  });
});

<p>i try to write a test for my react component that displays a button, and when clicked generates a xlsx file and offers to download.
for this i use these tools:</p>
<ul>
<li>react</li>
<li>vitest</li>
<li><a href="https://gitlab.com/catamphetamine/write-excel-file" rel="nofollow noreferrer">write-excel-file</a></li>
<li>FileSaver</li>
</ul>
<p>for this i found
<a href="https://stackoverflow.com/questions/44686077/how-to-use-jest-to-test-file-download">How to use Jest to test file download?</a></p>
<p>and tried to translate this jest example to my vitest enviroment:</p>
<pre class="lang-js prettyprint-override"><code>// ...
import FileSaver from "file-saver";
vi.mock("file-saver", () => {
return {
default: { saveAs: vi.fn() },
saveAs: vi.fn(),
};
});

global.Blob = function (content, options) {
return { content, options };
};

// ...
</code></pre>
<p>but i get</p>
<pre class="lang-js prettyprint-override"><code>FAIL src/MyExample/index.test.jsx > MyExample > check template download AssertionError:
expected "spy" to be called at least once ❯ src/MyExample/index.test.jsx:29:30
27| await user.click(btn);
28|
29| expect(FileSaver.saveAs).toHaveBeenCalled();
| ^
30| expect(FileSaver.saveAs).toHaveBeenCalledWith(
31| {
</code></pre>
<p>i have no idea if my basic concept can work at all..<br />
i thought that with this mock i replace the global FileSaver lib..<br />
but it seems this is not the case..<br />
i am a bit lost how to track this done and would like to learn too..<br />
i already extracted the saveAs part from the write-excel-file library to my own component so that it is a bit easier for me to understand what is going on..<br />
without success currently.</p>
<p><strong>What is the correct way / best practice to setup such a test case?</strong></p>
<p>my full example at <a href="https://codesandbox.io/p/devbox/rom...ar%22%3Atrue%2C%22sidebarPanelSize%22%3A15%7D" rel="nofollow noreferrer">codesandbox.io</a></p>
<p>my component looks like this</p>
<pre><code>import * as React from "react";
import { Button } from "@mui/material";

import writeXlsxFile from "write-excel-file";

export const MyExample = () => {
const exampleData = [
{
forename: "Diana",
surname: "Umlauft",
email: "[email protected]",
},
{
forename: "Jana",
surname: "Friedmann",
email: "[email protected]",
},
];

const columnsDefinition = [
{
column: "forename",
value: (person) => person.forename,
type: String,
width: 15,
},
{
column: "surname",
value: (person) => person.surname,
type: String,
width: 15,
},
{
column: "email",
value: (person) => person.email,
type: String,
width: 30,
},
];

async function handleDownloadExampleXLSX(event) {
console.log("handleDownloadExampleXLSX");
try {
const xlsxBlob = await writeXlsxFile(exampleData, {
schema: columnsDefinition,
// https://gitlab.com/catamphetamine/write-excel-file#browser
// when no fileName is given results in blob
fileName: `testFile.xlsx`,
});
//console.log("xlsxBlob", xlsxBlob);
// saveAs(xlsxBlob, `testFile.xlsx`);
} catch (error) {
console.log(error);
}
}

return (
<>
<Button onClick={handleDownloadExampleXLSX}>
Download Example
</Button>
</>
);
};

export default MyExample;

</code></pre>
<p>and my test file</p>
<pre><code>import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import MyExample from ".";

// based on https://stackoverflow.com/questions/44686077/how-to-use-jest-to-test-file-download
import FileSaver from "file-saver";
vi.mock("file-saver", () => {
return {
default: { saveAs: vi.fn() },
saveAs: vi.fn(),
};
});

global.Blob = function (content, options) {
return { content, options };
};

describe("MyExample", () => {
test("check template download", async () => {
const user = userEvent.setup();
const { container } = render(<MyExample />);
const btn = screen.getByText(/Download/i, {
selector: "button",
});
expect(btn).toBeInTheDocument();
await user.click(btn);

expect(FileSaver.saveAs).toHaveBeenCalled();
expect(FileSaver.saveAs).toHaveBeenCalledWith(
{
size: 5531,
options: {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
},
},
"testFile.xlsx",
);
});
});

</code></pre>
 

Latest posts

M
Replies
0
Views
1
Mohit Pant
M
Top