我可以在Cucumberjs上测试KnockOut ViewModel吗?

时间:2014-07-02 20:45:16

标签: knockout.js requirejs bdd cucumberjs

我定义了以下功能

Feature: Shoper can add an item to ShoppingCart

  Scenario: First item added to ShoppingCart
    Given I have an Empty ShoppingCart
    When I add an Item to ShoppingCart
    Then The ShoppingCart must have 1 item

  Scenario: Second item added to ShoppingCart
    Given I already have 1 item on my ShoppingCart
    When I add a second item to ShoppingCart
    Then The ShoppingCart must have 2 items

并使用CucumberJs生成步骤定义,如下所示:

'use strict';
module.exports = function () {
  this.Given(/^I have an Empty ShoppingCart$/, function (callback) {
    // Write code here that turns the phrase above into concrete actions
    callback.pending();
  });

  this.When(/^I add an Item to ShoppingCart$/, function (callback) {
    // Write code here that turns the phrase above into concrete actions
    callback.pending();
  });

  this.Then(/^The ShoppingCart must have (\d+) item$/, function (arg1, callback) {

    // Write code here that turns the phrase above into concrete actions
    callback.pending();
  });
}

但是我找不到为我的可观察视图模型创建实例的方法来测试它

function ShopCartViewModel() {
    var self = this;
    self.items = ko.observableArray([]);
    self.grandTotal = ko.computed(function() {
        var total = 0;
        ko.utils.arrayForEach(this.items(), function(item) {
            total += item.price();
        });

        return total.toFixed(2);
    }, this);

    self.getItemFromList    = function ( id ) {
        return ko.utils.arrayFirst(self.items(), function (item)
        {
            if (item.ProductId() === id()) {
                return item;
            }
        });
    }
}

我尝试加载knockout并在加载我的viewmodel之后:

  var ko = require('../../js/knockout-3.1.0');  
  var ShopCart = require('../../js/shopCartViewModel');

  var cart;

  console.log('ko :', ko); // <-defined
  console.log('cart :', ShopCart); // <- empty object {}

  this.Given(/^I have an Empty ShoppingCart$/, function (callback) {
    // Write code here that turns the phrase above into concrete actions
    cart = new ShopCart(); // <- error
    callback.pending();
  });

ko work,但ShopCart返回{}

如何在CucumberJs步骤定义中为ViewModel创建实例?

2 个答案:

答案 0 :(得分:3)

为了完成这项工作,需要在FrontEnd和Cucumber上使用RequireJs

前端

下载RequireJS并将其放入脚本文件夹

创建main.jsinit.js,该文件将定义并要求您的FrontEnd模块异步

require(['knockout-3.1.0', 'appViewModel'], function(ko, appViewModel) {
    ko.applyBindings(new appViewModel());
});

crie seu viewModelutilizandofunçãodefinedo requireJS

define(['knockout-3.1.0', 'shopCartItemViewModel'], function (ko, ShopCartItem) {
    return function ShopCart() {
        var self = this;
        self.items = ko.observableArray([]);
        self.grandTotal = ko.computed(function() {
            var total = 0;

            ko.utils.arrayForEach(self.items(), function(item) {
                total += parseFloat(item.NetValue());
            });

            return total;
        }, self.items);
    }
});

在前端,让RequireJs加载模块async

<script type="text/javascript" data-main="js/main.js" src="js/require.js"></script>

黄瓜

使用npm

安装RequireJs
npm install requirejs -g

创建另一个主文件,这次是针对节点的,因为存在一些不同的差异

file:main_node.js

var requirejs = require('requirejs');

requirejs(['knockout-3.1.0', 'shopCartViewModel' /*, 'appViewModel'*/], function(ko, shopCartViewModel) {
    //ko.applyBindings(new appViewModel());
});

现在,您只需要在您的cucmber步骤定义或所有测试的前挂钩中初始化requireJs

'use strict';
module.exports = function () {

    var assert = require('assert');
    var requirejs = require('requirejs');    
    var item = function (itemId) {
        return {
            id : itemId,
            nome: "Cookie " + itemId,
            itemQtd: 1,
            valorUnitario: 3.00,
            tipo: "Cookie",
            unitDiscount: 0.4
        }
    }

    requirejs.config({
      //path for your js files
      baseUrl: __dirname + '\\..\\..\\js',
      //Pass the top-level main.js/index.js require
      //function to requirejs so that node modules
      //are loaded relative to the top-level JS file.
      nodeRequire: require('../../js/main_node')
    });

    var ShopCart = requirejs('shopCartViewModel');

    var cart;

    this.Given(/^I have an Empty ShoppingCart$/, function (callback) {

        cart = new ShopCart();
        cart.items.removeAll();
        callback();
    });

    this.When(/^I add an Item to ShoppingCart$/, function (callback) {

        cart.addItemToCart(item(1));
        callback();
    });

    this.Then(/^The ShoppingCart must have (\d+) items$/, function (cartItemsCount, callback) {

        assert.equal(cart.getItemsCount(), cartItemsCount, 'ShopCart should have ' + cartItemsCount + ' items but have ' + cart.getItemsCount());
        callback();
    });

    this.Given(/^I already have (\d+) items on my ShoppingCart$/, function (itemsCount, callback) {

        cart.items.removeAll();
        for (i = 1; i <= itemsCount; i++) {
            (function (j) {
                cart.addItemToCart(item(j));
            }(i));
        }
        callback();
    });

    this.When(/^I add a second item to ShoppingCart$/, function (callback) {
        cart.addItemToCart(item(2));
        callback();
    });

    this.When(/^I add quantity of (\d+) to the first item$/, function (incrementCount, callback) {
        var itemFromCart = cart.getItemFromList(1);
        cart.addToItem(itemFromCart, incrementCount);
        callback();
    });

    this.Then(/^The first item must have a quantity of (\d+)$/, function (expectedItemCount, callback) {
        var itemFromCart = cart.getItemFromList(1);
        assert.equal(itemFromCart.quantidade(), expectedItemCount, 'Should have ' + expectedItemCount + ' items but have ' + itemFromCart.quantidade());
        callback();
    });

    this.When(/^I add (\d+) items to ShoppingCart$/, function (itemsCount, callback) {
        for (i = 1; i <= itemsCount; i++) {
            (function (j) {
                cart.addItemToCart(item(j));
            }(i));
        }
        callback();
    });

    this.Then(/^Shopping cart must have (\d+) value$/, function (netValue, callback) {
        console.log(cart.grandTotal());
        assert.equal(parseFloat(cart.grandTotal()), netValue, 'Total must be ' + netValue + ' but was ' + parseFloat(cart.grandTotal()));
        callback();
    });
}

最终结果

D:\Private\node\Projetos\siteBiscoitaria\public_www>cucumber-js
............

4 scenarios (4 passed)
12 steps (12 passed)

答案 1 :(得分:0)

您可以尝试使用加载knockout和viewmodel。

使用this example中的define

define("Main", ["knockout","TaskList", "Events", "Helpers"], 
       function (ko, obj, e, h) {
    var main  = function() {
        var self = this;
        self.Tasks = obj;
        self.Events = e;
        self.Helpers = h;
    }
    return new main(); //<= very important to return an object
});

您还可以查看this tutorial