为什么 Jest 覆盖率(伊斯坦布尔)在这个 Vue 组件方法中测量 0 个分支?

Why does Jest coverage (Istanbul) measure 0 branches in this Vue component method?

请考虑以下 - 有点做作 - 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 开玩笑时,我得到以下摘要报告:

=============================== 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';
    }
}

然后 Jest 确实计算了 1 个分支。

我的问题是 - 为什么 Jest / Istanbul 不将 onClick() 中的代码算作一个分支覆盖?

我想你误解了什么是分支。

一条语句类似于一行代码。分支只有在条件使某些语句执行或不执行时才能存在。

在下面的代码中,没有分支:

onClick() {
    this.text = 'bar';
}

这是因为没有if或任何其他类型的条件语句。

在下面的代码中,有 2 个分支:一个用于 if,一个用于隐式 else

onClick() {
    if (this.text != undefined) {
        this.text = 'bar';
    }
}

如果希望覆盖所有分支,需要在this.textundefined时添加测试。