如果我有一个包含函数的ES6类,则chai不会将两个相同的实例视为deepEqual。在这种情况下比较实例的正确方法是什么。
例如,给定此类定义
class Foo {
x;
constructor(x) {
this.x = x;
}
y = () => x*2;
}
前两个测试通过,但第三个测试失败
describe('class equality', function() {
it('compare single instance', function() {
var foo = new Foo(1);
assert.deepEqual(foo, foo);
});
it('compare string', function() {
assert.deepEqual(JSON.stringify(new Foo(1)), JSON.stringify(new Foo(1)));
});
it('compare instance', function() {
assert.deepEqual(new Foo(1), new Foo(1));
});
});
在这里展示(同样on jsFiddle - 注释第12行,所有三个测试都通过:
mocha.setup('bdd');
var assert = chai.assert;
class Foo {
x;
constructor(x) {
this.x = x;
}
y = () => x*2;
}
describe('class equality', function() {
it('compare single instance', function() {
var foo = new Foo(1);
assert.deepEqual(foo, foo);
});
it('compare string', function() {
assert.deepEqual(JSON.stringify(new Foo(1)), JSON.stringify(new Foo(1)));
});
it('compare instance', function() {
assert.deepEqual(new Foo(1), new Foo(1));
});
});
mocha.run();
<link href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.css" rel="stylesheet"/>
<div id="mocha"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.4.1/chai.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.js"></script>
答案 0 :(得分:1)
首先,让我们明确一点:那不是ES6课程。这是ES6(正式,ES2015 +)类加 类字段。类字段还不是语言的一部分;当我在2017年10月写这篇文章时,他们是Stage 3 proposal。您的
y = () => x*2;
...通过即将添加的(可能)语法向实例添加可枚举属性。 (与顶部附近的x;
一样。)它应该使用this
:
y = () => this.x*2;
// -------^^^^^
Chai显然正在比较所有可枚举的属性,即使它们是函数。您可以通过y
(或某天,在课程字段中使用decorator将您的Object.defineProperty
添加为不可枚举的属性;此时,他们'在构造函数中只修改阶段2):
Object.defineProperty(this, "y", {
value: () => this.x * 2
});
更新了代码段:
mocha.setup('bdd');
var assert = chai.assert;
class Foo {
x;
constructor(x) {
this.x = x;
Object.defineProperty(this, "y", {
value: () => this.x * 2
});
}
}
describe('class equality', function() {
it('compare single instance', function() {
var foo = new Foo(1);
assert.deepEqual(foo, foo);
});
it('compare string', function() {
assert.deepEqual(JSON.stringify(new Foo(1)), JSON.stringify(new Foo(1)));
});
it('compare instance', function() {
assert.deepEqual(new Foo(1), new Foo(1));
});
});
mocha.run();
console.log(new Foo(4).y());
<link href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.css" rel="stylesheet"/>
<div id="mocha"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.4.1/chai.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.js"></script>
那就是说,y
是一个非常好的候选人,而不是在原型上,这也解决了问题:
mocha.setup('bdd');
var assert = chai.assert;
class Foo {
x;
constructor(x) {
this.x = x;
}
y() {
return this.x * 2;
}
}
describe('class equality', function() {
it('compare single instance', function() {
var foo = new Foo(1);
assert.deepEqual(foo, foo);
});
it('compare string', function() {
assert.deepEqual(JSON.stringify(new Foo(1)), JSON.stringify(new Foo(1)));
});
it('compare instance', function() {
assert.deepEqual(new Foo(1), new Foo(1));
});
});
mocha.run();
<link href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.css" rel="stylesheet"/>
<div id="mocha"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.4.1/chai.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.js"></script>