Supose我有这样的功能:
function foo () {
obj.method(1);
obj.method(2);
obj.method(3);
}
为了测试它,我想做3次测试(使用Mocha TDD和Sinon):
test('medthod is called with 1', function () {
var expectation = sinon.mock(obj).expects('method').once().withExactArgs(1);
foo();
expectation.verify();
});
test('medthod is called with 2', function () {
var expectation = sinon.mock(obj).expects('method').once().withExactArgs(2);
foo();
expectation.verify();
});
test('medthod is called with 3', function () {
var expectation = sinon.mock(obj).expects('method').once().withExactArgs(3);
foo();
expectation.verify();
});
使用此系统,sinon在每次测试时都会出现“意外呼叫”消息。
我已经解决了将树测试加入其中的问题:
test('medthod is called with 1, 2 and 3', function () {
var mock = sinon.mock(obj);
mock.expects('method').once().withExactArgs(1);
mock.expects('method').once().withExactArgs(2);
mock.expects('method').once().withExactArgs(3);
foo();
mock.verify();
});
但我希望有三个测试,而不是一个有三个断言/期望的测试。
如何实现这一目标?
答案 0 :(得分:3)
与往常一样,当测试有些奇怪时,问题出在被测试的代码中。
在这种情况下,我们遭受耦合。目前该职能有两个职责:
要解决这个问题,我们必须将职责划分为两个函数/对象/类,然后分别测试每个函数/对象/类。例如,一种可能性是:
将测试第一个函数(生成并返回数据的函数),检查返回的数据是否符合我们的预期。
第二个函数(我们原来的函数)将有一个测试检查它调用数据生成器,然后测试检查它是否正确地将数据发送到期望的函数,第三个函数检查它是否调用函数根据数据需要多次。
代码将是这样的:
function foo() {
dataGenerator.generate().forEach(function (item) {
obj.method(item);
})
}
dataGenerator.generate = function () {
return [1,2,3];
};
测试:
test('generateData is called', function () {
var expectation = sinon.mock(dataGenerator).expects('generate').once();
foo();
expectation.verify();
});
test('method is called with the correct args', function () {
var expectedArgs = 1;
sinon.stub(dataGenerator, "generate").returns([expectedArgs]);
var expectation = sinon.mock(obj).expects('method').once().withExactArgs(expectedArgs);
foo();
expectation.verify();
});
test('method is called as many times as the amount of data', function () {
sinon.stub(dataGenerator, "generate").returns([1,2]);
var expectation = sinon.mock(obj).expects('method').twice();
foo();
expectation.verify();
});
test('dataGenerator.generate returns [1,2,3]', function () {
var expected = [1,2,3];
var result = dataGenerator.generate();
assert.equal(result, expected)
});
请注意,第三个测试仅检查调用方法的次数。第二个测试已检查数据是否正确传递,第四个测试本身是否正确。
答案 1 :(得分:0)
这是一个臃肿的版本,但这个解决方案可能有效。不确定你是否仍然需要它,但我只是在这里添加它。 http://jsfiddle.net/reyuto/jhkL7j34/
obj = {
method: function (param) {}
};
function foo() {
obj.method(1);
obj.method(2);
obj.method(3);
}
mock = sinon.mock(obj);
QUnit.test('method is called with 1', function () {
var expectation1 = mock.expects('method').once().withExactArgs(1);
var expectation2 = mock.expects('method').atLeast(2);
foo();
expectation1.verify();
expectation2.verify();
});
QUnit.test('method is called with 2', function () {
var expectation1 = mock.expects('method').atLeast(1);
var expectation2 = mock.expects('method').once().withExactArgs(2);
var expectation3 = mock.expects('method').atLeast(1);
foo();
expectation1.verify();
expectation2.verify();
expectation3.verify();
});
QUnit.test('method is called with 3', function () {
var expectation1 = mock.expects('method').once().withExactArgs(3);
var expectation2 = mock.expects('method').atLeast(2);
foo();
expectation1.verify();
expectation2.verify();
});