如何在组件中测试异步 vue 方法
Posted
技术标签:
【中文标题】如何在组件中测试异步 vue 方法【英文标题】:How to test an async vue method in component 【发布时间】:2020-03-05 02:27:21 【问题描述】:我正在尝试在我的 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 年微软公司。 Alle Rechte vorbehalten。
C:\Users\Philipp>cd..
C:\Users>cd..
C:>cd firebaseforum
C:\firebaseforum>npm run 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 真的
失败测试/单元/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.393s 运行所有测试套件。 Jest 在测试运行完成后一秒钟没有退出。
这通常意味着在您的测试中存在未停止的异步操作。考虑使用 --detectOpenHandles
运行 Jest 来解决此问题。
【问题讨论】:
【参考方案1】:我认为第二个测试通过了,因为当它运行时,第一个测试已经完成。如果你只在第二次测试中坚持,我认为它会失败。
我认为根本问题是您没有等待创建函数中的 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)
)
【讨论】:
如何等待函数?以上是关于如何在组件中测试异步 vue 方法的主要内容,如果未能解决你的问题,请参考以下文章