Skip to content

Testing

ahanusa edited this page Jan 28, 2019 · 11 revisions

peasy-js was designed from the ground up following the SOLID design principles. As a result, testing your classes that derive from peasy-js classes is easy.

This document provides guidance and examples of how to test your concrete implementations of peasy actors that should be tested. Note that these examples use jasmine and serve only as an example.

A word on unit testing styles

There is much debate around which stylistic unit tests are best, and essentially boils down to state-based vs. behavior-based unit tests. There are pros and cons to each approach and these will not be covered in this documentation.

With regards to state-based testing, you can easily create an in-memory data proxy for use in your unit tests.

Testing Rules

Given the following business rule ...

var CanSubmitOrderItemRule = Rule.extend({
  functions: {
    _onValidate: function(orderItem, context) {
      if (orderItem.id < 1) {
        this._invalidate("invalid id!");
      }
      return Promise.resolve();
    }
  }
});

Here's how you might test it:

describe("CanSubmitOrderItemRule", function() {
  it("succeeds when id > 0", function(onComplete) {
    var rule = new CanSubmitOrderItemRule({ id: 1 });
    rule.validate().then(() => {
      expect(rule.valid).toBe(true);
      onComplete();
    });
  });
  it("fails when id < 1", function(onComplete) {
    var rule = new CanSubmitOrderItemRule({ id: 0 });
    rule.validate().then(() => {
      expect(rule.valid).toBe(false);
      expect(rule.errors[0].message).toEqual("invalid id!");
      onComplete();
    });
  });
});

Testing commands

Given the following command...

var SubmitCommand = Command.extend({
  functions: {
    _getRules: function(id, dataProxy, context, done) {
      return dataProxy.getById(id).then(item => {
        return new CanSubmitOrderItemRule(item);
      });
    },
    _onValidationSuccess: function(id, dataProxy, context, done) {
      return dataProxy.submit(id);
    }
  }
});

Here's how you might test it:

  describe("SubmitCommand", function() {
    var orderItem = { id: 1, itemId: 1234, quantity: 4 };
    var dataProxy = {
      getById: function(id) {
        return Promise.resolve(orderItem);
      },
      submit: function(id) {
        return Promise.resolve(orderItem);
      }
    }

    it("submits the order item when the configured rule evaluates to true", function(onComplete) {
      CanSubmitOrderItemRule.prototype._onValidate = function() {
        return Promise.resolve();
      };
      var command = new SubmitCommand(1, dataProxy);
      command.execute().then(result => {
        expect(result.success).toEqual(true);
        onComplete();
      });
    });

    it("does not submit the order item when the configured rule evaluates to false", function(onComplete) {
      CanSubmitOrderItemRule.prototype._onValidate = function() {
        this._invalidate('cannot submit order item');
        return Promise.resolve();
      };
      var command = new SubmitCommand(1, dataProxy);
      command.execute().then(result => {
        expect(result.success).toEqual(false);
        onComplete();
      });
    });
  });

The above code tests how to make the command execution pass and fail by manipulating the configured rule.

Notice that we simply stubbed the _onValidate() function of the CanSubmitOrderItemRule in each test to manipulate the execution flow.

Clone this wiki locally