如何在组件中测试异步Vue方法

时间:2019-11-08 12:42:02

标签: javascript database firebase jestjs

我正在尝试在vue组件中测试我的checkConnection(),但我找不到正确的解决方案。第一个测试总是失败,第二个测试总是通过...而我不知道为什么。有人可以向我解释一下吗?

我的组件: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>

这是我的测试文件:

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();
  });
});

这是我运行npm run test:unit

时的错误

Microsoft Windows [版本10.0.18362.418] (c)2019 Microsoft Corporation。 Alle Rechte vorbehalten。

C:\ Users \ Philipp> cd ..

C:\ Users> cd ..

C:> cd firebaseforum

C:\ firebaseforum> npm运行test:unit

  

firebaseforum@0.1.0测试:C单元:\ firebaseforum   vue-cli-service测试:单位

console.log src / components / viewTopics.vue:31     连接需要一些时间

console.error node_modules / vue / dist / vue.runtime.common.dev.js:621     [Vue警告]:nextTick中的错误:“错误:expect(received).toEqual(expected)//深度相等

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)//深度平等

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     已连接

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

FAIL tests / unit / viewTopics.spec.js(6.694s)   ×此测试始终失败(5008ms)   √此测试始终通过(1ms)

●此测试始终失败

: 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)

测试套件:1个失败,总共1个 测试:1个失败,1个通过,总共2个 快照:共0个 时间:7.393秒 运行所有测试套件。 测试运行一秒钟后,Jest并没有退出。

这通常意味着您的测试中没有停止异步操作。考虑使用--detectOpenHandles运行Jest来解决此问题。

1 个答案:

答案 0 :(得分:0)

我认为第二项测试已通过,因为到它运行时,第一项测试已经完成。如果您只在第二项考试中坚持,我认为它将失败。

我认为潜在的问题是您不等待创建的函数中的checkConnection。

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>

我还要将shallowMount移到beforeEach中,以便为每个测试生成一个新实例。

就个人而言,我还发现使用async / await风格编写测试更加容易:

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