简体   繁体   中英

How to test an async vue method in component

i am trying to test my checkConnection() in my vue component and i can't get the right solution. The first test is always failing and the second one is always passing... and i don't get why. Can anybody explain this to me please?

My Component: viewTopics

  <div>
    {{isConnected}}
  </div>
</template>

<script>
import db from "./firebaseInit";

export default {
  name: "viewTopics",
  data: function() {
    return {
      isConnected: "just a random value"
    };
  },
  created() {
    this.checkConnection();
  },

  methods: {
    checkConnection() {
      var promise1 = new Promise(function(resolve) {
        var connectedRef = db.database().ref(".info/connected");
        connectedRef.on("value", function(snap) {
          if (snap.val() === true) {
            console.log("Connected");
            resolve(snap.val());
          } else {
            console.log("It takes some time to connect");
          }
        });
      });
      var self = this;
      promise1.then(function(value) {
        console.log(value);
        self.isConnected = true;

        //It sets the variable right but the test is not right
      });
    }
  }
};
</script>

<style scoped>
</style>

And here is my testing file:

import { shallowMount } from "@vue/test-utils";
import viewTopics from "@/components/viewTopics";


const wrapper = shallowMount(viewTopics);

test("This test is always failing ", done => {
  wrapper.vm.$nextTick(() => {
    expect(wrapper.vm.isConnected).toEqual(true);
    done();
  });
});

test("This test is always passing", done => {
  wrapper.vm.$nextTick(() => {
    expect(wrapper.vm.isConnected).toEqual(true);
    done();
  });
});

And here is my error when i run npm run test:unit

Microsoft Windows [Version 10.0.18362.418] (c) 2019 Microsoft Corporation. Alle Rechte vorbehalten.

C:\Users\Philipp>cd..

C:\Users>cd..

C:>cd firebaseforum

C:\firebaseforum>npm run test:unit

firebaseforum@0.1.0 test:unit C:\firebaseforum vue-cli-service test:unit

console.log src/components/viewTopics.vue:31 It takes some time to connect

console.error node_modules/vue/dist/vue.runtime.common.dev.js:621 [Vue warn]: Error in nextTick: "Error: expect(received).toEqual(expected) // deep equality

Expected: true
Received: "just a random value""

found in

---> <ViewTopics>
       <Root>

console.error node_modules/vue/dist/vue.runtime.common.dev.js:1884 JestAssertionError: expect(received).toEqual(expected) // deep equality

Expected: true
Received: "just a random value"
    at VueComponent.<anonymous> (C:\firebaseforum\tests\unit\viewTopics.spec.js:8:36)
    at Array.<anonymous> (C:\firebaseforum\node_modules\vue\dist\vue.runtime.common.dev.js:1976:12)
    at flushCallbacks (C:\firebaseforum\node_modules\vue\dist\vue.runtime.common.dev.js:1902:14)
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  matcherResult: {
    actual: 'just a random value',
    expected: true,
    message: [Function],
    name: 'toEqual',
    pass: false
  }
}

console.log src/components/viewTopics.vue:28 Connected

console.log src/components/viewTopics.vue:37 true

FAIL tests/unit/viewTopics.spec.js (6.694s) × This test is always failing (5008ms) √ This test is always passing (1ms)

● This test is always failing

: Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error:

  4 | const wrapper = shallowMount(viewTopics);
  5 |
> 6 | test("This test is always failing ", done => {
    | ^
  7 |   wrapper.vm.$nextTick(() => {
  8 |     expect(wrapper.vm.isConnected).toEqual(true);
  9 |     done();

  at new Spec (node_modules/jest-jasmine2/build/jasmine/Spec.js:116:22)
  at Object.<anonymous> (tests/unit/viewTopics.spec.js:6:1)

Test Suites: 1 failed, 1 total Tests: 1 failed, 1 passed, 2 total Snapshots: 0 total Time: 7.393s Ran all test suites. Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue.

I think the 2nd test is passing because by the time it runs, the 1st one has finished. If you stick an only on the 2nd test, I think it would fail.

I think the underlying issue is that you are not awaiting the checkConnection in the created function.

 new Vue({ el: '#app', name: "viewTopics", data () { return { isConnected: "just a random value" }; }, async created () { await this.checkConnection(); }, methods: { async checkConnection() { const promise1 = new Promise(function(resolve, reject) { const connectedRef = db.database().ref(".info/connected"); connectedRef.on("value", function(snap) { if (snap.val() === true) { console.log("Connected"); resolve(snap.val()); } else { console.log("It takes some time to connect"); reject('error msg') } }); }); try { const resultFromPromise = await promise1 this.isConnected = true console.log('Connected') } catch (error) { console.log(`error message: ${error}`) } } } })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> {{ isConnected }} </div>

I would also move the shallowMount into a beforeEach, so that a fresh instance is generated for each test.

Personally, I also find it easier to write the tests using the async/await style:

test("This test is always passing", async () => {
  await wrapper.vm.$nextTick()
  expect(wrapper.vm.isConnected).toEqual(true)
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM