undefined不是对象(评估'Board.offsetWidth')

时间:2017-06-18 11:24:22

标签: webpack phantomjs mocha karma-runner chai

我正在编写一个使用页面画布的测试。当我尝试获取此对象的offsetWidth时,会发生错误。如果我理解正确,问题是测试不知道从哪里获取html文件。

我的业力配置:

var webpackConfig = require('./webpack.config');
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['mocha', 'chai', 'sinon'],
files: [
  'src/index.pug',
  'test/**/*.ts'
],
exclude: [
],
preprocessors: {
  'test/**/*.ts': ['webpack'],
  'src/index.pug': ['pug', 'html2js']
},
webpack: {
  module: webpackConfig.module,
  resolve: webpackConfig.resolve
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['PhantomJS'],
singleRun: true,
concurrency: Infinity
})
}

1 个答案:

答案 0 :(得分:0)

你走在正确的轨道上。您需要有一个DOM可用,这意味着您需要在浏览器中运行测试或使用JSDOM在Node中创建虚假的浏览器环境。那部分没问题。

但是我们还没有看到你的任何测试。如果他们假设某种设置应该到位,例如将Board对象安装在某个DOM节点上,那么在测试之前需要一个设置阶段来创建这个新节点,将其添加到DOM,运行Board init代码,等。

编辑,得到代码:所以after looking at the code in question我在Board.ts中找到了这一行:

this.canvasBoard = <HTMLCanvasElement>document.getElementsByClassName('game__board')[0];

这假定存在具有类game__board的DOM节点。要使任何依赖于此的测试工作,您需要创建它(并在每次测试后清理它):

beforeEach(() => {
    const nodeNames = ['game__board', 'game__btn_play', 'game__btn_pause']; // add the rest ...
    nodeNames.forEach( (name) => {
        const elem = document.createElement('div');
        elem.classList.add(name);
        document.body.appendChild(elem);
     });
})

afterEach(() => {
    document.body.innerHTML = '';
});

上面的那一部分将创建所需的画布节点,但另一件事是你的代码是不正确的AFAIK。提到的行应该包含在constructor函数中,以便在创建对象时运行。

所以更改错误的初始化代码

this.canvasBoard = <HTMLCanvasElement>document.getElementsByClassName('game__board')[0];

constructor() {
    this.canvasBoard = <HTMLCanvasElement>document.getElementsByClassName('game__board')[0];
}

您可以验证第一个is incorrect on the TypeScript PlayGround