请考虑以下 - 有点做作 - Vue 组件:
<!-- FooBar.vue -->
<template>
<div @click="onClick">{{text}}</div>
</template>
<script>
export default {
name: 'foo-bar',
data() {
return {
text: 'foo'
}
},
methods: {
onClick() {
this.text = 'bar';
}
}
}
</script>
我已经用一个 Jest 单元测试覆盖了该组件,如下所示:
// FooBar.spec.js
import FooBar from '~/FooBar.vue';
import { shallowMount } from '@vue/test-utils';
import { expect } from 'chai';
describe('FooBar onClick()', () => {
it('should change the text to "bar"', () => {
// Arrange
const target = shallowMount(FooBar);
// Act
target.trigger('click');
// Assert
const div = target.find('div');
expect(div.text()).to.equal('bar');
});
});
测试通过绿色。
当我为此文件运行带有--coverage
的 Jest 时,我得到以下摘要报告:
=============================== Coverage summary ===============================
Statements : 0.1% ( 2/1868 )
Branches : 0% ( 0/1402 )
Functions : 0% ( 0/505 )
Lines : 0.2% ( 2/982 )
================================================================================
如您所见,单元测试涵盖的分支数显示为 0 - 即使 Jest(或者更准确地说是 Instanbul,Jest 在幕后使用覆盖)确实检测到测试覆盖了两行代码。
当我做了一个小实验并在onClick()
中添加了一个if
语句时,如下所示:
onClick() {
if (this.text != undefined) {
this.text = 'bar';
}
}
那么杰斯特确实数了 1 个分支覆盖。
我的问题是 - 为什么 Jest/Istanbul 不将onClick()
中的代码计为涵盖的分支?
我猜你误解了分支是什么。
语句类似于一行代码。只有当条件执行或不执行某些语句时,分支才能存在。
在下面的代码中,没有分支:
onClick() {
this.text = 'bar';
}
这是因为没有if
或任何其他类型的条件语句。
在下面的代码中,有 2 个分支:一个用于if
,一个用于隐式else
。
onClick() {
if (this.text != undefined) {
this.text = 'bar';
}
}
如果您希望涵盖所有分支,则需要在undefined
this.text
时添加一个测试。