仅当使用括号调用函数时,Vue 模板中的函数调用测试才会通过

Gio*_*sta 7 javascript vue.js jestjs vue-test-utils

我将 Vue v2.6 与 Jest (v24.9) 和 Vue-Test-Utils (v1.03) 一起使用。

为了模拟一个方法,我看到了两种不同的语法,

wrapper.vm.updateCart = jest.fn();
Run Code Online (Sandbox Code Playgroud)

和

wrapper.setMethods({ updateCart: jest.fn() });
Run Code Online (Sandbox Code Playgroud)

但第一个没有记录,而第二个已被弃用(请参阅文档)。

问题是,使用这两种方法,测试通过的唯一方法是在模板内调用带有括号的方法,这很奇怪,因为我读过的所有文档都以某种方式鼓励使用模板中不带括号的方法。

所以这个测试:

test('Click on .btn calls the right function', () => {
    const wrapper = shallowMount(Modal, {
        propsData: {
            validate: jest.fn(),
        },
    });
    wrapper.setMethods({ updateCart: jest.fn() });
    const $btn = wrapper.find('.btn');
    $btn.trigger('click');
    expect(wrapper.vm.updateCart).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

仅当我用括号调用该方法时才会通过:

<button class="btn" @click="updateCart()">
  {{ dictionary('remove') }}
</button>
Run Code Online (Sandbox Code Playgroud)

但否则会失败(例如使用@click="updateCart")。

测试模板中的事件是否正在调用函数的正确语法是什么?

为什么文档中的弃用警告(此处和此处)将setMethodapi 定义为反模式?

也许只测试模板中的事件触发函数是错误的,因为这种行为应该已经由框架(Vue)保证,而我们应该只专注于测试函数本身?

编辑 07/02/2020

我还尝试了不同的语法:

const spy = jest.spyOn(wrapper.vm, 'updateCart');
const $btn = wrapper.find('.btn');
$btn.trigger('click');
expect(spy).toHaveBeenCalled();
Run Code Online (Sandbox Code Playgroud)

这可以防止覆盖该方法并替换对 的调用setMethods,但测试仍然仅在使用括号调用该函数时通过。

Est*_*ask 6

支持@click="updateCart"和@click="updateCart()"语法变体,这很令人困惑,因为 Vue DSL 允许在v-on. 前者使用updateCart方法作为事件处理程序,而后者根据组件实例计算表达式,并且不限于方法。

\n

@click="updateCart()"出于一致性原因,更可取,因为表达式通常在 Vue 模板中使用,在抛出错误@click="notAFunction"时也会默默失败。@click="notAFunction()"这也允许通过以下方式监视它:

\n
jest.spyOn(wrapper.vm, 'updateCart');\n
Run Code Online (Sandbox Code Playgroud)\n

否则,需要在组件实例化之前监视该方法:

\n
jest.spyOn(Modal.methods, 'updateCart');\nconst wrapper = shallowMount(Modal);\n
Run Code Online (Sandbox Code Playgroud)\n

setMethod已弃用的解释如下:

\n
\n

没有明确的路径来替换 setMethods,因为它实际上取决于您以前的用法。它很容易导致依赖于实现细节的片状测试,这是不鼓励的。

\n

...

\n

要存根复杂的方法,请从组件中提取它并在隔离中测试它。要断言调用了某个方法,请使用测试运行程序对其进行\nspy。

\n
\n

对测试实施的担忧是主观的,因为这通常不是一件坏事。提取是否实用取决于具体情况,因为一个函数需要提取到另一个模块才能被监视。

\n

至于updateCart,模拟更新 car\xd0\xb5 的底层 API 可能就足够了,而不是方法本身。

\n

使用存根方法测试点击事件仍然可能有用,或者至少监视真实的方法。以这种方式测试的是模板,而不仅仅是框架的行为。如果没有间谍,测试失败是否是因为btn或是未知的updateCart。

\n