Quantcast
Channel: Kendo UI – Falafel Software Blog
Viewing all articles
Browse latest Browse all 43

Testing a Kendo ViewModel DataSource

$
0
0

Welcome to the next step on the road to testing! So far I’ve shown a way to take the ordinary, one-off way of defining ViewModels and moving towards defining a ViewModel “class” so that one can be bound to the UI and others can be unit tested. I also took a detour to explain some nuances of how defining Kendo classes work with regards to what goes into a class’ prototype versus what goes into a specific instance. This time, I am going to take these concepts and discuss some specific complications you might encounter when attempting to test a DataSource, and how to solve those problems.

The first thing you’ll have to decide when adding a DataSource to an ObservableObject subclass is, where to declare it? Thinking back to the last post, you already know that if you define the DataSource outside of the init function, that property will become part of the prototype, shared with all instances of the subclass. I think we would want each instance to have its own data, so for the majority of cases, you should add the DataSource definition during the init function.

When you have a ViewModel with a DataSource in it, one thing you might want to be able to do is to have some properties on the ViewModel that are used by the DataSource when making server requests. If that ViewModel was created the “normal” way by initializing a variable with kendo.observable(), then it’s easy to read the ViewModel instance just by referencing the variable. But how do you accomplish the same task when you define the ViewModel as a class instead of as an instance? It’s actually quite simple: obtain the self-reference within init() and then reference it from within other functions declared in init()’s function scope. For example, see this snippet:

init: function(values) {
    var self = this,
        defaultValues = {
          blogCount: 2
        };
    kendo.data.ObservableObject.fn.init.call(this, $.extend({}, defaultValues, values));
    this.set('dataSource', new kendo.data.DataSource({
      transport: {
        read: {
          url: 'blog.falafel.com/api/adam-anderson/',
          data: function() {
            return {
              type: 'recent',
              count: self.blogCount
            };
          }
        }
      },
      schema: {
        data: 'data'
      }
    }));
  }

In this example, a self-reference is obtained and then the ViewModel is initialized with a property named blogCount. Next, a DataSource is added with a function provided for the read transport’s data option. This function will be called any time the DataSource makes a read request, and it will use the self-reference obtained in init()’s function scope to read from this instance of the ViewModel.

AJAX mocking with Jasmine

Jasmine provides the ability to mock AJAX results with an optional module that you must explicitly reference and install into Jasmine before using it. There are a number of ways to use it, but for this example, I’m going to show the simplest approach, which is to perform the setup and teardown within a test method. It’s possible to perform the same tasks in a suite’s setup and teardown functions instead as well as predefine certain responses to specific requests as well. Let’s take a look at the example:

it('can test DataSources', function() {
    jasmine.Ajax.withMock(function() {
      viewModel.set('blogCount', 3);
      viewModel.dataSource.fetch(); // Sends AJAX request which is caught by Jasmine.Ajax
      var dataSourceRequest = jasmine.Ajax.requests.mostRecent();
      // You can inspect the URL
      expect(dataSourceRequest.url).toEqual('blog.falafel.com/api/adam-anderson/?type=recent&count=3');
      // You can specify a response synchronously
      dataSourceRequest.response({
        'status': 200,
        'contentType': 'application/json',
        'responseText': '{"data":[{"title":"Testable ViewModels with Kendo and Jasmine","date":"1/20/2015"},{"title":"Kendo ObservableObject subclasses: prototype vs init","date":"1/23/2015"},{"title":"Testing Kendo DataSources (working title)","date":"2/10/2015"}]}'
      });
      // Now the DataSource should contain the data
      expect(viewModel.dataSource.data().length).toEqual(3);      
    });
  });

Let me break this down for you step by step. First of all, you make a call to jasmine.Ajax.withMock and pass a function containing the steps to test. This test starts by setting the blogCount property and then telling the DataSource to make a request. Since this is occurring within withMock(), the AJAX request is caught by Jasmine and will not respond until you tell Jasmine what to respond with. At this point, you can inspect the request to perform tests on it. This test expects that the DataSource will make a request passing the blogCount value to the server in the QueryString variable ‘count’. Next, the test provides a response. Note that this response must be valid JSON, so for example, all the property names must be enclosed in double quotes. One simple way to obtain this raw JSON response is to make a real request to the server and then use a tool like the Chrome Dev Tools to obtain the raw response and paste it into your test. Lastly, the the test validates that the DataSource is correctly configured to parse the server response, which returns the data in a property named ‘data’. As usual, I have a full working sample available on JSBin.

With this technique, you now have the ability to define and test a wide range of logic within a ViewModel. The goal should be for all of the page or section’s behavior to be expressed within the ViewModel and completely ignorant of the presence (or absence) of a DOM. Of course, sometimes this is not 100% possible; for example, if your page needs to perform some custom animations, then the animations do need to reference the DOM. However, consider moving those animations to custom MVVM bindings, as demonstrated here. The more you can move the UI-specific code into bindings and out of the ViewModel, the more testable the ViewModel will be!

The post Testing a Kendo ViewModel DataSource appeared first on Falafel Software Blog.


Viewing all articles
Browse latest Browse all 43

Trending Articles