Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用karma实现mock #18

Open
renaesop opened this issue Nov 4, 2016 · 0 comments
Open

使用karma实现mock #18

renaesop opened this issue Nov 4, 2016 · 0 comments

Comments

@renaesop
Copy link
Owner

renaesop commented Nov 4, 2016

karma是一个著名的浏览器测试框架,他的特色是启动一个nodejs服务器,在浏览器端通过http下载脚本,并通过websocket实现karma和浏览器实现双向通信。

网上甚少有使用karma做mock的教程。但是因为karma使用了connect模块,有中间件的能力,因此值得一试。

引入karma

karma官方支持的是jasmine,所以省事一点就直接用jasmine(不过这货返回promise没有官方支持)。

  • 在项目中新建文件karma.conf.js
module.exports = config => {
    config.set({
        basePath: './test',
        files: ['**/*.spec.js'],
        browsers : [
          'Chrome',
        ],
        frameworks: ['jasmine'],
        singleRun: true,
    });
}
  • 新建 test/entry.spec.js
describe('Hello, test', () => {
    it('should work', () => {
        const data = 0;
        expect(data).toEqual(0);
    });
});
  • 安装依赖
    npm i karma karma-jasmine karma-chrome-launcher jasmine-core -D

  • 执行测试
    node_modules/.bin/karma start

执行之后,可以看到浏览器被自动打开然后关闭,控制台出现一片绿色提示,表示测试成功了。

实现mock

吐槽一下,karma深受Java/AngularJS的影响,什么都搞依赖注入,怪恶心的。

karma支持插件,插件的结构应该如此:

.......
// optional
fn.$injector = [xxx, xxx ,xxx]

module.exports = {
    `${plugin type}:${plugin name}`: [`${fn type, factory or value}`, fn]
}

插件主要有4种类型分别是 frameworks, reporters, launchers and preprocessors, 另外还有我们要用的middleware。

插件默认会接收到config作为参数(就是我们写的配置文件),也可以通过对fn执行$injector属性指定fn被注入的参数。

如此我们就开始实现一个我们的middleware。

  • 新建 test/mock/middleware.js 文件
// 比较简单,当路径匹配到指定的mockUriStart时
// 则加载processors下的模块处理请求

function mockFactory(config) {
  const mockUrl = config.mockUriStart || '/mock-api/';
  return function (req, res, next) {
    if (req.url.indexOf(mockUrl) === 0) {
      const path = req.url.slice(mockUrl.length);
      try {
        const processor = require(`./processors/${path}`);
        processor(req, res);
      }
      catch (e) {
        next();
      }
    }
    else {
      next();
    }
  };
};
// 我们只需要config,因此就不指定$injector属性了
module.exports = {
  'middleware:mock': ['factory', mockFactory]
};
  • 新建 test/mock/processors/simple.js文件
module.exports = function (req, res) {
  res.end('Simple data');
};
  • 修改karma.conf.js, 这里有个大坑点,如果你想加载不处于node_modules的插件,则需要手动在plugins中添加。但是一旦有了plugins选项,那么所有的插件加载都要手动添加,包括在node_modules中的插件。
module.exports = config => {
    config.set({
        basePath: './test',
        files: ['**/*.spec.js'],
        browsers : [
          'Chrome',
        ],
        frameworks: ['jasmine'],
        middleware: ['mock'],
        plugins: [
            require('./test/mock/middleware'),
            require('karma-jasmine'),
            require('karma-chrome-launcher'),
        ],
        singleRun: true,
    });
}
  • 修改 test/entry.spec.js
describe('Hello, test', () => {
    it('should work', (done) => {
       const xhr = new XMLHttpRequest();
       xhr.open('GET', '/mock-api/simple', true);
       xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
               console.log(xhr.response);
               done();
             }
      };
    xhr.send(null);
    });
});
  • 执行测试
    node_modules/.bin/karma start

将会看到karma的控制台有LOG: 'Simple data'的字样。

至此,就完成了一个简单的mock server,只要扩充mock中间件对路由的处理逻辑或者让mock中间件做其他mock服务器的代理,就可以拥有更加完整的功能。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant