使用 Jest 进行测试时无法执行单击 Vuetify vSwitch

Posted

技术标签:

【中文标题】使用 Jest 进行测试时无法执行单击 Vuetify vSwitch【英文标题】:Unable to perform click on Vuetify vSwitch when testing with Jest 【发布时间】:2020-03-23 00:08:57 【问题描述】:

我目前正在为实现 Vuetify Switch 的 Vue 组件编写测试。作为测试的一部分,我想检查 vuetify 开关的功能。我在触发点击开关时遇到麻烦,然后验证开关值是否已更改(一旦完成,我将验证绑定到开关的值也已更改)

我查看了 Vuetify 的 API 文档,没有任何方法可以直接设置 Vuetify 开关的状态,这在我看来令人困惑。因此,我尝试使用wrapper.find().trigger('click') 对 VSwitch 组件进行点击,但这并没有改变开关值,让我相信点击根本没有做任何事情。

下面是两个测试

第一个检查开关在创建时是否具有正确的状态,即通过 第二个尝试执行单击事件并检查状态是否已更改,但失败

对于解决此问题的任何帮助将不胜感激。

switch.vue

<template>

    <v-row>
        <v-col>
            <label class="label-text" :for="`$fieldLabel`">labelText</label>
            <v-row>
                <label class="left-label">toggleLeftText</label>
                <v-switch
                        :id="`$fieldLabel`"
                        v-model="toggleState"
                        class="ma-0 pa-0"
                        :data-qa="`$fieldLabelCheckbox`"
                >
                </v-switch>
                <label class="right-label">toggleRightText</label>
            </v-row>
            <!--Hidden input field includes switch value in form when submitted-->
            <input type="hidden" :value="toggleState" :name="`$fieldLabel`">
        </v-col>
    </v-row>


</template>

<script>
    export default 
        name: "Switch",
        props: 
            fieldLabel: 
                type: String,
                required: true
            ,
            labelText: 
                type: String,
                required: true
            ,
            toggleLeftText: 
                type: String,
                required: true
            ,
            toggleRightText: 
                type: String,
                required: true
            ,
            toggleValue: 
                type: Boolean,
                required: true
            ,

        ,

        data: function () 
            return 
                toggleState: this.toggleValue
            
        

    
</script>

switch.spec.js


describe('Switch', () => 

    const toggleState = true;

    const localVue = createLocalVue();
    localVue.use(Vuetify, 
        components: 
            VRow,
            VCol,
            VSwitch,
            InputError
        
    );

    const wrapperFactory = () => 
        return shallowMount(Switch, 
            localVue,
            vuetify: new Vuetify(),
            propsData: testProps,
        );
    ;

    const testProps = 
        labelText: "Test Label",
        fieldLabel: "testLabel",
        toggleLeftText: "No",
        toggleRightText: "Yes",
        toggleValue: toggleState
    ;

    let wrapper;

    beforeEach(() => 
        wrapper = wrapperFactory(testProps);
    );

    afterEach(() => 
        wrapper.destroy();
    );

    it("should have correct toggle value", () => 
        const vSwitch = wrapper.find(VSwitch);
        expect(vSwitch.vm.value).toBe(toggleState);
    );

    it("should have correct toggle value after click", async () => 
        const vSwitch = wrapper.find(VSwitch);
        await vSwitch.trigger('click');
        expect(vSwitch.vm.value).toBe(!toggleState);
    );
);

【问题讨论】:

【参考方案1】:

我回答你的问题可能有点晚了,但这样你应该可以得到你的v-switch

const vSwitch = wrapper.find( name: 'v-switch' );

然后触发事件

vSwitch.$emit('change', &lt;true or false&gt;);,取决于您要测试的内容。

这种方法的限制是,如果您的代码中有多个v-switches,则需要使用data-test-id 来定位它们,例如:

<v-switch data-test-id="my-switch-1"> ... </v-switch>;
<v-switch data-test-id="my-switch-2"> ... </v-switch>;

然后我在测试文件的顶部定义了一个辅助函数,如下所示:

const getSwitchComponent = (wrapper: Wrapper<Vue>, testId: string): Wrapper<Vue> => 
  const switches = wrapper.findAll( name: 'v-switch' );
  const component = switches.wrappers.find(wrapper =>
    wrapper.contains(`[data-test-id="$testId"]`),
  );

  if (!component) 
    throw Error(`Element not found: $testId`);
  

  return component;
;

这会让你做这样的事情:

const mySwitch1 = getSwitchComponent(wrapper, 'my-switch-1');
const mySwitch2 = getSwitchComponent(wrapper, 'my-switch-2');

并触发change 事件:

mySwitch1.vm.$emit('change', false);
mySwitch2.vm.$emit('change', true);

【讨论】:

以上是关于使用 Jest 进行测试时无法执行单击 Vuetify vSwitch的主要内容,如果未能解决你的问题,请参考以下文章

当模拟点击调用调用 promise 的函数时,使用 React 的 Jest 和 Enzyme 进行测试

SyntaxError:无法在模块外使用 import 语句:运行 Jest-expo 测试时

无法让 Jest expo 应用程序与 react-navigation 一起使用

使用 Vue.js 和 Jest 进行 URL 重定向测试

使用 Jest、AudioContext 进行测试和模拟

使用 Jest 进行测试 - TypeError:无法读取未定义的属性“forEach”