Search code examples
javascriptunit-testingjasminespyon

how do I test my load function using jasmine if it has been called?


This function is reading data from a JSON file and prints it out. it not supposed to be in a class. I'm having hard time testing it if has been called.

function load(nameString) {
  nameString = nameString.toLowerCase().split(" ");
  const fs = require("fs");
  fs.readFile(
    `visitor_${nameString[0]}_${nameString[1]}.json`,
    "utf8",
    (err, visitorInfo) => {
      if (err) {
        console.log("Error reading file from disk:", err);
        return;
      }
      try {
        console.log(JSON.parse(visitorInfo));
      } catch {
        console.log("Error parsing visitor info", err);
      }
    }
  );
}

Solution

  • For "jasmine": "^3.6.3", You can use spyOn(obj, methodName) to install a spy onto fs.readFile() method. Use callFake(fn) to tell the spy to call a fake implementation when invoked. We can get and invoke the callback of fs.readFile() in test case with error or normal value.

    load.js:

    function load(nameString) {
      nameString = nameString.toLowerCase().split(' ');
      const fs = require('fs');
      fs.readFile(`visitor_${nameString[0]}_${nameString[1]}.json`, 'utf8', (err, visitorInfo) => {
        if (err) {
          console.log('Error reading file from disk:', err);
          return;
        }
        try {
          console.log(JSON.parse(visitorInfo));
        } catch {
          console.log('Error parsing visitor info', err);
        }
      });
    }
    
    module.exports = load;
    

    load.test.js:

    const fs = require('fs');
    const load = require('./load');
    
    describe('69014390', () => {
      it('should read file', () => {
        spyOn(fs, 'readFile').and.callFake((path, options, callback) => {
          callback(null, JSON.stringify({ name: 'teresa teng' }));
        });
        spyOn(console, 'log');
        load('teresa teng');
        expect(fs.readFile).toHaveBeenCalledWith('visitor_teresa_teng.json', 'utf8', jasmine.any(Function));
        expect(console.log).toHaveBeenCalledWith({ name: 'teresa teng' });
      });
    
      it('should handle error', () => {
        const error = new Error('ENOENT');
        spyOn(fs, 'readFile').and.callFake((path, options, callback) => {
          callback(error);
        });
        spyOn(console, 'log');
        load('teresa teng');
        expect(fs.readFile).toHaveBeenCalledWith('visitor_teresa_teng.json', 'utf8', jasmine.any(Function));
        expect(console.log).toHaveBeenCalledWith('Error reading file from disk:', error);
      });
    });
    

    test result:

    Executing 2 defined specs...
    Running in random order... (seed: 74926)
    
    Test Suites & Specs:
    
    1. 69014390
       ✔ should read file (6ms)
       ✔ should handle error (1ms)
    
    >> Done!
    
    
    Summary:
    
    👊  Passed
    Suites:  1 of 1
    Specs:   2 of 2
    Expects: 4 (0 failures)
    Finished in 0.019 seconds