Creating mocks with Breeze.js

Breeze.js is a powerful library you can leverage in your Single Page Applications.  It plays nicely with all other technologies, and is designed to provide rich client-side data.  You can easily it with your application, regardless of the tech stack.  Don’t believe me?  Prove otherwise.  The authors of Breeze.js have certainly shown you can in their samples – http://www.breezejs.com/samples – (Side note: check out the ESPN sample, whoever made it is a genius)

Mocks –

Most applications have need for mocks.  Mocks can be especially powerful when you are building out the front-end and the back-end isn’t entirely ready yet.  You can also use them for writing unit tests against data without having to populate from the server.  I won’t get into testing in this post because there are so many ways to test and the tests can be very opinionated.

The only requirement for mocks is that you need to have your metadata in place first, either from the server or as the Breeze.js authors mention in the docs you can also get a snapshot of your metadata and pass it in when mocking. This is a great way to iterate and update your models. (Reference – http://www.breezejs.com/documentation/load-metadata-script)

Example –

function loadMocks (manager) {
    var personMockOne = manager.createEntity('Person', { id: 1, firstName: 'John', lastName: 'Smith' });
    var companyMockOne = manager.createEntity('Company', { id: 1, name: 'Acme Inc.' });
    companyMockOne.employees.push(personMockOne);
}

That’s it! We now have mocks we can run our tests against or build out our pages. Calling loadMocks() and passing in our manager will add the mocks to our entity collection and we can start testing. We pass in the manager to keep our function anonymous, and in the above example I am adding the employee mock to the company’s employees collection, but we could just as easily create the company and then set the company property on the person to companyMockOne. Example –

var companyMockOne = manager.createEntity('Company', { id: 1, name: 'Acme Inc.' });
var personMockOne = manager.createEntity('Person', { id: 1, firstName: 'John', lastName: 'Smith', company: companyMockOne });

You will notice when using this technique that the entityState of the entities are added. If you have logic in your page related to saving or cancelling changes, this could potentially trigger your UI to think the mocks need to be saved. We can easily get around that as well by calling acceptChanges() on the entityAspect of the entity. Example –

var companyMockOne = manager.createEntity('Company', { id: 1, name: 'Acme Inc.' });
companyMockOne.entityAspect.acceptChanges();

This will let Breeze know that you are comfortable with the changes made to the company and they do not need to be persisted to back to the database. While you could also chain the entityAspect.acceptChanges() onto the end of the createEntity method, beware that this will no longer return the entity.

var companyMockOne = manager.createEntity('Company', { id: 1, name: 'Acme Inc.' }).entityAspect.acceptChanges();
// The next line will not console log our entity
console.log(companyMockOne);

I often use this method for create enumerations as well that aren’t strictly passed down from a server. This can be especially useful when using someone else’s API where they aren’t exposing all of the data you need. Last Example –

manager.createEntity('Priority', { id: 1, name: 'Severe', imageSource: 'severe.jpg' }).entityAspect.acceptChanges();

This can be especially useful if you are re-using the enum all over your application.

I hope you find this useful, please leave any feedback below, especially if you see any errors. Direct any trouble-shooting questions to StackOverflow.com, and check out the Breeze.js UserVoice for feedback or feature requests.

Advertisements

Best parts about Durandal

I wanted to start a quick series dedicated to what makes Durandal so powerful to yield.

Part 1 – 

The Compose binding

With Durandal, you can dynamically load views and AMD modules directly from the DOM.  Why is this important?

  1. You can separate your views and modules into the smallest bits of (re-usable) code needed.
  2. Render your content more dynamically.
  3. You can easily instantiate and show either Singleton objects or Constructors.  (wait what?)

Separating your code

Imagine you want to create ‘n’ number of widgets that are in charge of their own visibility, data-fetching, and data-binding.  Easy.  Using the compose binding with a foreach, you can instantiate the modules in your view model and use the DOM to render them.

View –

<ul data-bind="foreach: widgets">
     <li data-bind="compose: widgetPath"></li>
</ul>

View Model –

define([], function () {
    var widgets = ko.observableArray();
    function initializeViewModel() {
        widgets.push(new Widget('Compose a widget module', 'viewmodels/exampleone'));
        widgets.push(new Widget('Compose a widget view only', 'exampletwo'));
    }
    function activate() {
        initializeViewModel();
    }
    function Widget(title, path) {
        var self = this;
        self.Title = title;
        self.widgetPath = path;
    }
});

What did we just do?

1. When we initiated the view model, we added two widgets into an observable array containing widgets.
2. The first widget is a path to a view model, which Durandal finds an associated view for and properly recognizes as part of a module.
3. The second widget is a path to a view, with no corresponding view model.

Whats interesting to note here is that in the first widget with a corresponding view model, Durandal helps us by creating a context around that view that is bound to the view model. This means if we reference something in the view model that Knockout and Durandal bind any related view elements to that instance of the view model. This is most ideal when not using singletons, as the every instance of a singleton will be bound to the same context.

In the second widget we are simply binding to the current context, which in this case would be the widget.  This is derived from the foreach binding that the widget is nested inside of, so you could easily bind to the title property or you could also reference the parent context using the Knockout $parent reference.

The reason $parent would not work in the first example is that the new context does not directly know who the parent is.  What if we wanted it to?  That’s easy as well, using activationData

Activation Data –

Using the activationData option of the compose binding, we can inject data or even context into the composed view model.  This is an excellent way of injecting dependency, and I could go on for hours on the various ways you can use this in your application, but let’s keep it simple and show an example.

Let’s bind our view up to widgets using Knockout’s containerless binding –

<!-- ko foreach: widgets -->
    <!-- ko compose: { model: widgetPath, activationData: { data: $data } } -->
    <!-- /ko -->
<!-- /ko -->

You’ll notice that I passing an object into the compose binding that contains a model and activationData, which contains an object of it’s own. You can read more on the Durandal website on the various parameters (http://durandaljs.com/documentation/Using-Composition.html) but basically the model is declaring that at that path, there is a view model to use for binding. Durandal automatically finds the corresponding view, and then injects our activationData into the view model. To intercept it, you only need to have a parameter in your activate method of the widget. Notice I am injecting $data, which basically just injects the current context into the view model. You could just as easily inject strings, observables, and even parent contexts.

Grabbing the data in our widget’s view model –

define([], function () {
    var thisContext = ko.observable();
    function activate(activationData) {
        // Set thisContext equal to the injected data
        thisContext(activationData.data);    
    }
    function Widget(title, path) {
        var self = this;
        self.Title = title;
        self.widgetPath = path;
    }
});

Now you can bind thisContext in the view however you want. A solid strategy is to use the with binding in your view that is set to thisContext, that way if for some reason your view model is instantiated without data it will just appear empty as opposed to breaking your bindings.

That’s it! Feel free to leave comments if you notice any problems or have any suggestions or questions. If you have any Durandal questions please direct them to StackOverflow.com or the Durandal.js Google Group, where the active community will help resolve them.