deko
deko

Reputation: 181

how to mock variables inside a function in jest

I want to test the 'canViewPage method in jest. How do mock the const userPages which is the values from the func getUserPage

   canViewPage(page){
     const userPages = getUsersPages();
    if(userPages.includes(page)){
      return true;
    }
    return false;
   }


  getUsersPages(){
    // here i hardcode a list of pages, for simplicity purposes
    const pages = ['home','about','contact'];
    return pages

  }



here is what i tried

test('test canViewPage', () => {
    const spy = jest.spyOn(canViewPage, 'userPages');
    spy.mockReturnValue(['home','about','contact']);

    expect(canViewPage('premiumPage')).toBe(false); 

    spy.mockRestore();
  });

I also tried this

test('test canViewPage', () => {
    const spy = jest.spyOn(canViewPage, 'getUsersPage');
    spy.mockReturnValue(['home','about','contact']);

    expect(canViewPage('premiumPage')).toBe(false); 

    spy.mockRestore();
  });

Upvotes: 12

Views: 73086

Answers (3)

Naga
Naga

Reputation: 11594

This is not Jest but sinon, in case if you can not see the instance of the target class, you can also set mock values as below. Once specified, mocked values will be returned until sinon.restore() called

const sinon = require('sinon');
const test = await sinon
    .stub(MyAwesomeClass.prototype, 'getUsersPages')
    .returns(['mockItem1','mockItem2','mockItem3']);

const instance = new MyAwesomeClass()
console.log(instance.getUserPages()) // <- this return ['mockItem1','mockItem2','mockItem3']

It assume that this is target source code.

// MyAwesomeClass.js
export default class MyAwesomeClass {
  canViewPage(page) {
    const userPages = this.getUsersPages();
    if (userPages.includes(page)) {
      return true;
    }
    return false;
  }
    
  getUsersPages() {
    // here i hardcode a list of pages, for simplicity purposes
    const pages = ['home', 'about', 'contact'];
    return pages;
  }
}

// test.js
import MyAwesomeClass from '<path to MyAwesomeClass.js>'
test('test canViewPage', () => {
  const instance = new MyAwesomeClass()
  const spy = jest.spyOn(instance, 'getUsersPages');
  spy.mockReturnValue(['mockItem1','mockItem2','mockItem3']);

  expect(instance.canViewPage('premiumPage')).toBe(false);
  expect(instance.canViewPage('mockItem1')).toBe(true);

  spy.mockRestore();
});

Upvotes: 0

kishorekumaru
kishorekumaru

Reputation: 1578

Spy and stub is a recommended approach, however in case if you want to access the outside scope object, hack window variable and assign it with desired value

for ex:

var a = 10;
const myfun = () => {
 return a + 20;
}

test('myfun', () => {
  window.a = 20
  expect(myfun).toBe(40)
 }

Upvotes: -1

macphilips
macphilips

Reputation: 557

To mock the value of userPages you have to mock getUserPage. To achieve this, it depends on where and how getUserPage and canViewPage are defined. I'm going to assuming these two functions are defined in class MyAwesomeClass

// MyAwesomeClass.js
export default class MyAwesomeClass {
  canViewPage(page) {
    const userPages = this.getUsersPages();
    if (userPages.includes(page)) {
      return true;
    }
    return false;
  }


  getUsersPages() {
    // here i hardcode a list of pages, for simplicity purposes
    const pages = ['home', 'about', 'contact'];
    return pages;
  }
}

// test.js
import MyAwesomeClass from '<path to MyAwesomeClass.js>'
test('test canViewPage', () => {
  const instance = new MyAwesomeClass()
  const spy = jest.spyOn(instance, 'getUsersPages');
  spy.mockReturnValue(['mockItem1','mockItem2','mockItem3']);

  expect(instance.canViewPage('premiumPage')).toBe(false);
  expect(instance.canViewPage('mockItem1')).toBe(true);

  spy.mockRestore();
});

if canViewPage and getUsersPages are static methods within the class, you mock differently

test('test canViewPage', () => {
  const spy = jest.spyOn(MyAwesomeClass, 'getUsersPages');
  spy.mockReturnValue(['mockItem1','mockItem2','mockItem3']);

  expect(MyAwesomeClass.canViewPage('premiumPage')).toBe(false);
  expect(MyAwesomeClass.canViewPage('mockItem3')).toBe(true);

  spy.mockRestore();
});

Upvotes: 12

Related Questions