【问题标题】:How to access Vuejs methods to test with Jest?如何访问 Vuejs 方法以使用 Jest 进行测试?
【发布时间】:2019-07-18 23:45:44
【问题描述】:

我有以下文件:deposit-form.js

使用以下代码:

new Vue({
    el: '#app',
    data: {
        title: 'title',
        depositForm: {
            chosenMethod: 'online',
            payMethods: [
                { text: 'Already paid via Venmo', value: 'venmo' },
                { text: 'Pay online', value: 'online' },
                { text: 'In-person payment', value: 'person' }
            ],         
        },
    },
    methods: {
        submitDeposit: function() {
            $.ajax({
                url: 'http://localhost:8000/api/v1/deposit/',
                type:'post',
                data: $('#deposit-form').serialize(),
                success: function() {
                    $('#content').fadeOut('slow', function() {
                        // Animation complete.
                        $('#msg-success').addClass('d-block');
                    });
                },
                error: function(e) {
                    console.log(e.responseText);
                },
           });
        },
        showFileName: function(event) {
            var fileData =  event.target.files[0];
            var fileName = fileData.name;
            $('#file-name').text('selected file: ' + fileName);
        },
    },
});

我在如何设置 Jest、如何在“方法”中导入 VueJs 函数以使用 Jest 进行测试时遇到问题。

deposit-form.test.js 上的代码应该如何?

【问题讨论】:

    标签: unit-testing vue.js jestjs


    【解决方案1】:

    您需要做的第一件事是导出 Vue 应用实例。

    // deposit-form.js
    
    import Vue from 'vue/dist/vue.common';
    
    export default new Vue({
        el: '#app',
        data: {...},
        ...
    });
    

    现在您可以在规范文件中使用此代码。但是现在你需要在运行测试之前拥有#app 元素。这可以使用 jest 设置文件来完成。我将解释为什么需要它。当您将主文件 (deposit-form.js) 导入测试时,会在您的主文件中创建一个带有 new 的 Vue 实例。 Vue 正在尝试将应用程序挂载到 #app 元素中。但是这个元素不在你的 DOM 中。这就是为什么您需要在运行测试之前添加此元素。

    在此文件中,您还可以全局导入 jQuery 以在您的测试中使用它,而无需单独导入。

    // jest-env.js
    
    import $ from 'jquery';
    
    global.$ = $;
    global.jQuery = $;
    
    const mainAppElement = document.createElement('div');
    mainAppElement.id = 'app';
    document.body.appendChild(mainAppElement);
    
    

    Jest 设置文件必须在 package.json 的 jest 配置部分中指定。

    // package.json
    
    {
        ...,
        "dependencies": {
            "jquery": "^3.3.1",
            "vue": "^2.6.7"
        },
        "devDependencies": {
            "@babel/core": "^7.0.0",
            "@babel/plugin-transform-modules-commonjs": "^7.2.0",
            "@babel/preset-env": "^7.3.4",
            "@vue/test-utils": "^1.0.0-beta.29",
            "babel-core": "^7.0.0-bridge.0",
            "babel-jest": "^24.1.0",
            "babel-loader": "^8.0.5",
            "babel-preset-vue": "^2.0.2",
            "jest": "^24.1.0",
            "vue-jest": "^3.0.3",
            "vue-template-compiler": "^2.6.7",
            "webpack": "^4.29.5",
            "webpack-cli": "^3.2.3"
        },
        "scripts": {
            "test": "./node_modules/.bin/jest --passWithNoTests",
            "dev": "webpack --mode development --module-bind js=babel-loader",
            "build": "webpack --mode production --module-bind js=babel-loader"
        },
        "jest": {
            "moduleFileExtensions": [
                "js",
                "json",
                "vue"
            ],
            "transform": {
                "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
                ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
            },
            "setupFiles": [
                "<rootDir>/jest-env.js"
            ]
        }
    }
    

    此外,您可能需要配置 Babel 以在您的项目和测试中使用 ES6 的功能。如果您在代码中遵循 commonjs 样式,则不需要这样做。基本.babelrc 文件包含下一个代码:

    // .babelrc
    
    {
        "presets": [
            [
              "@babel/preset-env",
              {
                "useBuiltIns": "entry",
                "targets": {
                  "browsers": [
                    "last 2 versions"
                  ]
                }
              }
            ],
            "vue",
        ],
        "plugins": [
            "@babel/plugin-transform-modules-commonjs",
        ]
    }
    

    现在您可以编写测试了。

    // deposit-form.test.js
    
    import App from './deposit-form';
    
    describe('Vue test sample.', () => {
        afterEach(() => {
            const mainElement = document.getElementById('app');
    
            if (mainElement) {
                mainElement.innerHTML = '';
            }
        });
    
        it('Should mount to DOM.', () => {
            // Next line is bad practice =)
            expect(App._isMounted).toBeTruthy();
    
            // You have access to your methods
            App.submitDeposit();
        });
    });
    
    

    我的建议是学习Vue Test Utils Guides 并开始将您的代码分成组件。使用当前的方法,您将失去组件的所有功能以及测试 vue 应用程序的能力。


    我稍微更新了我的答案。正如我从评论到答案所理解的那样,您将页面上的库连接为单独的文件。这是我的错误。我没有问是否正在使用构建系统。我的示例中的代码是用 ECMA-2015 标准编写的。但是,不幸的是,浏览器并不完全支持它。您需要一个转译器,将我们的文件转换为浏览器可以理解的格式。听起来很难。但这不是问题。作为回应,我更新了文件package.json 的内容。现在只剩下为程序集创建一个输入文件并运行程序集本身了。

    输入文件很简单。

    // index.js
    
    import './deposit-form';
    

    从终端使用以下命令开始构建。

    # for development mode
    $ yarn run dev
    # or
    $ npm run dev
    
    # for production mode
    $ yarn run build
    # or
    $ npm run build
    

    输出文件将放置在目录./dist/ 中。现在,您只需要连接一个文件,而不是单独的文件。它包含库和您的代码所必需的所有内容。

    我使用 webpack 构建。有关它的更多信息,请参阅documentation。您可以在 this article 中找到很好的示例。

    【讨论】:

    • 您的回答非常有用,我可以设置 Jest 并运行测试!但是现在当我运行我的 deposit-form.html 时,我遇到了一个错误。控制台向我指出以下错误: Uncaught SyntaxError: Unexpected identifier on line: 1 import Vue from 'vue/dist/vue.common.js It doesn't identify 'Vue' 你知道为什么会这样吗?
    • 我为冗长的回答道歉。我更新了问题的答案。这应该可以解决问题。
    猜你喜欢
    • 2021-09-16
    • 2018-03-04
    • 2022-01-14
    • 2021-08-11
    • 2018-11-09
    • 2020-05-17
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    相关资源
    最近更新 更多