最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to check if a method is called in nested jest mock functions - Stack Overflow

programmeradmin4浏览0评论

I have a mock service like below

  const firebaseService = jest.fn(() => ({
    initializeApp: jest.fn(() => { /*do nothing*/}),
  }))

in my test I want to expect if initializeApp has been called. How can I check that?

it('should be called', () => {
   expect(???).toHaveBeenCalledTimes(1);
});

Update : Real scenario

  const collection = jest.fn(() => {
    return {
      doc: jest.fn(() => {
        return {
          collection: collection,
          update: jest.fn(() => Promise.resolve(true)),
          onSnapshot: jest.fn(() => Promise.resolve(true)),
          get: jest.fn(() => Promise.resolve(true))
        }
      }),
      where: jest.fn(() => {
        return {
          get: jest.fn(() => Promise.resolve(true)),
          onSnapshot: jest.fn(() => Promise.resolve(true)),
          limit: jest.fn(() => {
            return {
              onSnapshot: jest.fn(() => Promise.resolve(true)),
              get: jest.fn(() => Promise.resolve(true)),
            }
          }),
        }
      }),
      limit: jest.fn(() => {
        return {
          onSnapshot: jest.fn(() => Promise.resolve(true)),
          get: jest.fn(() => Promise.resolve(true)),
        }
      })
    }
  });

  const Firestore = {
    collection: collection
  }

    firebaseService = {
      initializeApp() {
        // do nothing
      },
      firestore: Firestore
    };

and I want to check below

 expect(firebaseService.firestore.collection).toHaveBeenCalled();
 expect(firebaseService.firestore.collection.where).toHaveBeenCalled();    
 expect(firebaseService.firestore.collection.where).toHaveBeenCalledWith(`assignedNumbers.123`, '==', true);

I have a mock service like below

  const firebaseService = jest.fn(() => ({
    initializeApp: jest.fn(() => { /*do nothing*/}),
  }))

in my test I want to expect if initializeApp has been called. How can I check that?

it('should be called', () => {
   expect(???).toHaveBeenCalledTimes(1);
});

Update : Real scenario

  const collection = jest.fn(() => {
    return {
      doc: jest.fn(() => {
        return {
          collection: collection,
          update: jest.fn(() => Promise.resolve(true)),
          onSnapshot: jest.fn(() => Promise.resolve(true)),
          get: jest.fn(() => Promise.resolve(true))
        }
      }),
      where: jest.fn(() => {
        return {
          get: jest.fn(() => Promise.resolve(true)),
          onSnapshot: jest.fn(() => Promise.resolve(true)),
          limit: jest.fn(() => {
            return {
              onSnapshot: jest.fn(() => Promise.resolve(true)),
              get: jest.fn(() => Promise.resolve(true)),
            }
          }),
        }
      }),
      limit: jest.fn(() => {
        return {
          onSnapshot: jest.fn(() => Promise.resolve(true)),
          get: jest.fn(() => Promise.resolve(true)),
        }
      })
    }
  });

  const Firestore = {
    collection: collection
  }

    firebaseService = {
      initializeApp() {
        // do nothing
      },
      firestore: Firestore
    };

and I want to check below

 expect(firebaseService.firestore.collection).toHaveBeenCalled();
 expect(firebaseService.firestore.collection.where).toHaveBeenCalled();    
 expect(firebaseService.firestore.collection.where).toHaveBeenCalledWith(`assignedNumbers.123`, '==', true);
Share Improve this question edited Aug 1, 2019 at 17:32 Reza asked Jul 31, 2019 at 19:52 RezaReza 19.9k16 gold badges98 silver badges173 bronze badges 5
  • would it be easier to use mocking package like firebase-mock? to me mocking such variety of methods manually might be really hard – skyboyer Commented Aug 1, 2019 at 15:54
  • @skyboyer I tried to use that, it mocks the methods (github./danleavitt0/firebase-mock/blob/master/src/…), but none of them are jest.fn, so I am not able to check if they are called or not, see this github./soumak77/firebase-mock/issues/150 – Reza Commented Aug 1, 2019 at 16:37
  • but do you really need that? I mean if API is mocked - so you know what it responds - and ponent renders as expected - does it really matter what exact API calls has been done and when? – skyboyer Commented Aug 1, 2019 at 18:19
  • @skyboyer good point, what is the best practice? do we need to check if dependencies are called with specific args or just receiving mock response is enough? – Reza Commented Aug 1, 2019 at 18:22
  • don't have 100% confidence on that but since I've migrated from asserting everything to asserting only outes(wherever it ponent, independent function or model class) my tests stop breaking on each internal refactoring :) so I believe it's so named implementation details we should ignore for better unit testing. Just personal opinion though. – skyboyer Commented Aug 1, 2019 at 18:27
Add a ment  | 

1 Answer 1

Reset to default 9

You can define the inner spy as a variable.

const initializeAppSpy = jest.fn(() => { /*do nothing*/});

const firebaseService = jest.fn(() => ({
    initializeApp: initializeAppSpy,
}))

Then you can use the reference in order to expect on it:

it('should be called', () => {
   expect(initializeAppSpy).toHaveBeenCalledTimes(1);
});

EDIT You can create a mock to the entire service

const firebaseMock = {
   method1: 'returnValue1',
   method2: 'returnValue2'
}

Object.keys(firebaseMock).forEach(key => {
   firebaseMock[key] = jest.fn().mockReturnValue(firebaseMock[key]);
});

const firebaseService = jest.fn(() => firebaseMock);

now, you will have a firebaseMock object that all the methods are mocked. you can expect on each one of those methods.

发布评论

评论列表(0)

  1. 暂无评论