0

I'm trying to test a component that loads data asynchronously when mounted. The component works as expected, it's just the test that's giving me issues. The component's async loadData() function hangs at await axios.get() while jest test runner is in the component.vm.$nextTick(). As a result, the checks in the $nextTick loop never pass.

Immediately after the $nextTick loop times out, the component's await statement completes and the component renders itself. axios is mocked, so it should resolve really fast. If I remove the await and just fill in a constant instead, the entire thing executes as expected.

I'm guessing that $nextTick loop is not asynchronous and it's consuming the thread, even though this is the recommended way of testing asynchronous stuff. The problem is, I don't have an onclick async handler to await: this method is called from onMount.

Unfortunately, I don't know how to make a jsFiddle of this one, so I hope this will be enough:

my component (the relevant parts)

    export default {
      data() { return { content: '' }; },
      mounted() { this.loadDoc() }
      methods: {
        async loadDoc() {
          const res = await axios.get('some url'); // <-- this is the line that hangs until timeout
          // const res = { data: 'test data'}; // this would test just fine
          this.content = res.data;
        }
      }
    }

and my component.spec.js:

    jest.mock('axios', () => ({
      get: async (url) => {
        return { data: 'test data' };
      }
    };

    describe('my super test', () => {
      it('renders', (done) => {
        const doc = shallowMount(myComponent);
        doc.vm.$nextTick(() => {
          expect(doc.html()).toContain('test data'); // <-- this never matches
          done();
        });
      });
    });
eXception
  • 1,307
  • 1
  • 7
  • 22
velis
  • 8,747
  • 4
  • 44
  • 64

1 Answers1

0

I would delete, but I just spent quite some hours for something that was suggested in the docs, but not explained that it's the only way... I'm hoping somebody else finds this useful.

Using flush-promises package instead of $nextTick loop immediately "fixed" the problem

Code sample (rework of above):

describe('my super test', () => {
  it('renders', async() => {
    const doc = shallowMount(myComponent);
    await flushPromises();
    expect(doc.html()).toContain('test data'); // <-- now it works
  });
});
velis
  • 8,747
  • 4
  • 44
  • 64
  • Is it a way to access methods in tests? Like `doc.vm.loadDoc()`? Cause for me all the methods are `undefined` when there is a top-level await existed. I've made a question for that her: https://stackoverflow.com/q/74192860/16280429 Will be appreciated for answering. – eXception Oct 26 '22 at 11:44