我正在尝试使用jasmine测试一些视图代码。当视图对象处于不同的包含状态时,我需要测试某些元素的存在,而不必在每个状态中重复大量代码。
我有NodeView类,它代表一个带有一些端点的节点,以便允许用户将这个节点连接到带有某些行的其他节点。每个节点都放在一个列(组)中,这样如果将此节点放入第一个组,它将不会显示左端点。如果节点进入最后一个组,则不会显示正确的端点。我可以使用jasmine中的嵌套describe块来管理这种情况:
var node, subject, model;
describe("render", function() {
beforeEach(function() {
model = mockModel();
});
describe("when the node is into first group", function() {
beforeEach(function () {
model.isInFirstGroup.andReturn(true);
model.isInLastGroup.andReturn(false);
node = new NodeView(model);
});
it("has the left endpoint hidden", function() {
expect(node.el.find('.endpoint .left')).toBeHidden();
});
it("has the right endpoint visible", function() {
expect(node.el.find('.endpoint .left')).toBeVisible();
});
});
describe("when the node is into last group", function() {
beforeEach(function () {
model.isInFirstGroup.andReturn(false);
model.isInLastGroup.andReturn(true);
node = new NodeView(model);
});
it("has the left endpoint visible", function() {
expect(node.el.find('.endpoint .left')).toBeVisible();
});
it("has the right endpoint hidden", function() {
expect(node.el.find('.endpoint .left')).toBeHidden();
});
});
到目前为止一切正常。当我们有其他不同的状态时,麻烦就开始了,在这种情况下,这种状态是允许输入的。这是一个布尔值,表示用户是否可以绘制线条。如果此布尔值为true,则节点必须包含“输入”类以及其他内容。这是代码(再次渲染函数):
describe("when the node is in input state", function() {
beforeEach(function() {
model.input = true;
node = new NodeView(model);
});
it("has the class input", function(){
expect(node.el).toHaveClass('input');
});
});
describe("when the node is not in input state", function() {
beforeEach(function() {
model.input = false;
node = new NodeView(model);
});
it("has not the class input", function(){
expect(node.el).not.toHaveClass('input');
});
});
好吧,我在构建节点时测试生成的html标记(不显式调用render方法),但它在内部完成了这项工作。在构建对象时(构造函数调用render)调用Render,这就是我不在代码中显式调用node.render()的原因。
测试这些不同的状态需要测试包括所有可能的情况:
如果我添加另一个布尔状态,则Ill有8个场景,依此类推。我尝试使用共享示例http://pivotallabs.com/drying-up-jasmine-specs-with-shared-behavior/
进行一点清理sharedExamplesForGroupState = function() {
describe("(shared)", function() {
describe("when the node is into first group", function() {
beforeEach(function () {
model.isInFirstGroup.andReturn(true);
model.isInLastGroup.andReturn(false);
node = new NodeView(model);
});
it("has the left endpoint hidden", function() {
expect(node.el.find('.endpoint .left')).toBeHidden();
});
it("has the right endpoint visible", function() {
expect(node.el.find('.endpoint .left')).toBeVisible();
});
});
describe("when the node is into last group", function() {
beforeEach(function () {
model.isInFirstGroup.andReturn(false);
model.isInLastGroup.andReturn(true);
node = new NodeView(model);
});
it("has the left endpoint visible", function() {
expect(node.el.find('.endpoint .left')).toBeVisible();
});
it("has the right endpoint hidden", function() {
expect(node.el.find('.endpoint .left')).toBeHidden();
});
});
});
});
describe("when the node is in input state", function() {
beforeEach(function() {
model.input = true;
node = new NodeView(model);
});
it("has the class input", function(){
expect(node.el).toHaveClass('input');
});
sharedExamplesForGroupState();
});
describe("when the node is not in input state", function() {
beforeEach(function() {
model.input = false;
node = new NodeView(model);
});
it("has not the class input", function(){
expect(node.el).not.toHaveClass('input');
});
sharedExamplesForGroupState();
});
上面的行不能按预期工作,因为输入状态测试是在没有设置输入状态的情况下完成的,因此,我们真正测试的是:
这并不是真正测试所有4个案例。
关于如何改进这一点以避免指数重复代码的任何想法?
非常感谢。
答案 0 :(得分:2)
我认为最新的describe块上的beforeEach正在注册的回调函数正被sharedExamplesForGroupState()调用的beforeEach调用所覆盖。如果为sharedExamplesForGroupState调用创建一个新范围(比如将其封装到describe块中),它应该可以工作:
describe("when the node is in input state", function() {
beforeEach(function() {
model.input = true;
node = new NodeView(model);
});
it("has the class input", function(){
expect(node.el).toHaveClass('input');
});
describe("shared examples for group state", function() {
sharedExamplesForGroupState();
});
});