Put Jest to the test by testing the appendFileSync function

I am currently working on creating a test for appendfilesync function. When using a logger, I noticed that one line of code is not covered in my tests. Below is the code snippet I am referring to (please note that I am using tslog for logging purposes):

export function logToTransport(logObject: ILogObject) {
  appendFileSync('monopoly_deal.log', JSON.stringify(logObject) + '\n');
}

I have attempted to mock 'fs' in order to prevent actual file writing during testing, but this method does not allow me to properly test the writing functionality. Here is the beginning of my test setup code:

const log: Logger = new Logger({ name: 'card_types_test' });
    log.attachTransport(
      {
        silly: CardTypes.logToTransport,
        debug: CardTypes.logToTransport,
        trace: CardTypes.logToTransport,
        info: CardTypes.logToTransport,
        warn: CardTypes.logToTransport,
        error: CardTypes.logToTransport,
        fatal: CardTypes.logToTransport,
      },
      'info',
    );

// To intercept the call without executing it, I believe I need to set up jest.spyon. However, I am unsure about the correct approach. Possibly something like const spy = jest.fn(CardTypes.logToTransport);

log.info('test'); // Writes to the log file
expect(spy).toequal({object with my data}); // The specific structure of the object has been omitted for brevity.

Any advice on how to simulate file writing in my tests would be highly valuable, as well as any other suggestions or feedback (as I am still relatively new to programming).

Answer №1

When testing the code logic, it is advisable to focus on the logToTransport function rather than the fs.appendFileSync method. The latter is a built-in Node.js method that is already well-tested.

If needed, you can mock the fs.appendFileSync method, also known as mocking partials, to test the inner workings of the logToTransport function. This approach aligns with white-box testing.

In addition, you can use jest.isMockFunction to confirm if the mocking partials were implemented successfully.

For example:

index.ts:

import { appendFileSync } from 'fs';

type ILogObject = any;
export function logToTransport(logObject: ILogObject) {
  appendFileSync('monopoly_deal.log', JSON.stringify(logObject) + '\n');
}

index.test.ts:

import fs from 'fs';
import { logToTransport } from '.';

jest.mock('fs', () => ({
  ...(jest.requireActual('fs') as typeof fs),
  appendFileSync: jest.fn(),
}));
describe('73466276', () => {
  test('should pass', () => {
    expect(jest.isMockFunction(fs.appendFileSync)).toBeTruthy();
    expect(jest.isMockFunction(fs.appendFile)).toBeFalsy();
    logToTransport({ level: 'debug', payload: { name: 'teresa teng' } });
    expect(fs.appendFileSync).toBeCalledWith(
      'monopoly_deal.log',
      JSON.stringify({ level: 'debug', payload: { name: 'teresa teng' } }) + '\n'
    );
  });
});

Test result:

 PASS  stackoverflow/73466276/index.test.ts (11.306 s)
  73466276
    ✓ should pass (3 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 index.ts |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        12.012 s

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The argument provided must be a string comprising of either 12 bytes, a string containing 24 hex characters, or an integer in order to avoid a BSONTypeError

After building a CRUD application using the MERN stack, I attempted to implement a search operation but encountered an error: BSONTypeError: Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer Below is the code ...

Adjust image size while maintaining aspect ratio

Currently, I am implementing a resize function for an image by using the following code snippet: $('.image_resize').each(function(){ var ww = $(window).width() - 80 - 400; var wh = $(window).height() - 60; var iar = $(this).attr(&apo ...

Routes for Express are throwing a 500 internal server error

My server is unable to locate the APIs that I have created in the API directory, which is resulting in a 500 internal server error. I have thoroughly checked routes.js and everything appears to be correct. Additionally, I have an error.js file for handlin ...

The style of MUI Cards is not displaying properly

I've imported the Card component from MUI, but it seems to lack any styling. import * as React from "react"; import Box from "@mui/material/Box"; import Card from "@mui/material/Card"; import CardActions from "@mui/m ...

I need to update a JSON file on the server by adding a new object to the existing array using the fs.appendFile function

I have a JSON stored on the server like this: [{"a":1}, {"a":2}] and I'm wondering if there is a way to add an object at the end without having to rewrite the entire file on the server. As a workaround, I have been omitting the brackets and adding the ...

Stop the print dialog box from appearing when using the Ctrl + P shortcut

I'm working on an Angular app and I want to prevent the print dialog from opening when pressing "Ctrl + P". To address this issue, I have implemented the following code: window.onbeforeprint = (event) => { event.stopPropagation(); cons ...

Alert from Google Chrome about Service Worker

My situation involves using FCM for sending web notifications. However, I am encountering a warning and the notifications are not functioning as expected when clicked (i.e., opening the notification URL). Below is my Service-Worker code: importScripts(& ...

Updating the Highcharts chart when new data is available

Utilizing Highcharts, I am looking to have this chart update every second. Here's my current setup: JSFiddle I've implemented a timer with window.setInterval(updateChart, 1000); which successfully updates data each second. However, I'm uns ...

Is it possible for a kraken.js backend to manipulate the content of a webpage?

Currently using kraken.js, which is an express.js framework, to construct a localized website. Within the header section, there are 3 language options provided as links. FR | EN | DE My goal is to have the link corresponding to the currently set locale ( ...

Can config values be dynamically set from an Excel file in Protractor?

I am currently working on parameterizing capabilities using an Excel sheet. For this task, I am utilizing the npm exceljs package for both reading and writing data. Below is a snippet of the code that demonstrates how I am trying to achieve this: //This f ...

Production environment does not support Meteor environment variables

I am currently deploying my app using Meteor UP and I have set the environment variables in both the mup.json file and a file called server/lib/env.js where they are stored. Here is how the variables are being accessed: Meteor.startup(function() { // ...

The Material UI Checkbox is displaying duplicate values within a single instance

Using React and Material UI checkbox I want the checkbox to update a specific value in the state when it's checked. While everything seems to be working fine, I've noticed that on the first 2 clicks of the checkbox the state doesn't update ...

Sending data from PHP to JavaScript using JSON encoding through POST requests

I am dealing with a multi-dimensional array that needs to be passed to a PHP script using JavaScript to parse JSON data and display it on Google Maps. I am experimenting with using forms to achieve this: <?php $jsontest = array( 0 => array( ...

Steps for referencing an autogenerated id in a Firestore collection

I need assistance updating a 'progress' field in a document with an autogenerated ID (using Firestore) every time the progress button is clicked. https://i.stack.imgur.com/hZieN.png Despite my attempts, nothing seems to work. Here is the method ...

How can I use XPATH to target a div after choosing a nested element?

I had the task of creating a universal identifier to locate a dropdown menu following a label. There are 10 different forms, each with a unique structure but consistent format, which means I cannot rely on specific IDs or names. Instead, my approach was to ...

Choosing the subsequent element that comes before

<tr class="main"></tr> <tr class="emails-details"> <button>some button</button> </tr> <tr class="main"></tr> <tr class="emails-details"> <button>some button</button> </tr> &l ...

What causes jquery height and javascript height to both be returned as 0?

I'm facing an issue with a visible div on my screen - despite being visible, its height always returns as 0. I've attempted various jQuery and JavaScript methods to retrieve the height, but it consistently shows as 0. Here's the structure of ...

Tips for modifying the color or personalizing the header arrow for the expandableRow within Mui Datatable

My MUI data table has the expandable rows option, along with an ExpandAll button in the header row. The arrow displayed in the title row is confusing for users as it's similar to the arrows in all other rows. I want to change the color of the header a ...

Unit Testing Angular: Passing FormGroupDirective into a Function

I am currently writing unit tests for a function that takes a parameter of type FormGroupDirective. I have been able to test most of the logic, but I'm unsure about what to pass as a parameter when calling the resetForm() function. Here is the code sn ...

Issue: Unhandled rejection TypeError: Unable to access properties of an undefined variable (retrieving 'data')

Currently, I am developing applications using a combination of spring boot for the backend and react for the frontend. My goal is to create a form on the client side that can be submitted to save data in the database. After filling out the form and attemp ...