Test Filters in AngularJS

  • Estimated read time: 4 min read
  • Written by Chad Campbell on Feb 1st 2014

One of AngularJS's core concepts are filters. Filters are used to prepare an expression's result for the user. In other words, to convert one value to another. This is useful for things like converting a boolean true or false to a more user-friendly 'yes' or 'no'. In fact, that example will be used in this blog post to show how to test filters in AngularJS with Jasmine. You can view the demo or download the code.

Verify that the filter is loaded

When unit testing filters, the first thing to test is if they're available. It can be easy to assume a filter is available for use. However, a filter may be in a module that hasn't been loaded. Or, if your JavaScript is merged via a build process, the filter code may not be included in your scripts. A unit test verifies these two things. Here is a unit test that determines if a filter is available.

it('should load the filter', inject(function ($filter) {
  var myFilter = $filter('myFilter');
  expect(myFilter).toBeDefined();
}));

In line #2 we are creating an instance of our filter. At this point in the game our only concern is that the filter is loaded. If you have a simple filter, now is the time to verify the filter works.

Verify the filter works

A lot of the time, you'll use a filter from your HTML markup. For instance, MyFilter (which you can see in the code), converts true and false to 'yes' and 'no'. An example of using this filter in HTML can be seen here:

{{ true | MyFilter }}

The above shows the most basic use of a filter. To unit test a filter though, you'll probably use JavaScript instead of HTML. To test a filter using JavaScript, you can call it just like any other function. For example, to test MyFilter with Jasmine, you could use the following:

it('should show "yes" when true is passed', inject(function ($filter, $log) {
    var myFilter = $filter('MyFilter');
    var result = myFilter(true);
    expect(result).toBe('yes');
}));

This example shows how to verify if a filter works. However, this example doesn't show how to test a filter that takes parameters.

Testing filters with parameters

When you're developing filters, your scenario may require the use of parameters. To pass parameters to a filter from the declarative HTML world, you could do something like the following:

{{ true | MyFilter:'sir' }}

This snippet shows the syntax of passing a parameter to a filter. If your filter required more parameters, you could append ':[parameterValue]' for each additional parameter. To unit test a filter that takes parameters, you can use Jasmine again. Once again, you're just calling a JavaScript function as shown here:

it('should include the postfix if provided', inject(function($filter, $log) {
    var myFilter = $filter('MyFilter');
    var result = myFilter(true, 'sir');
    expect(result).toBe('yes sir');
}));

This past example doesn't show much new. In fact, the three tests written up to this point have been basic, even contrived. In reality, you only need to write the first test that we wrote. The past two tests have been provided to show you the syntax of writing tests. Either way, at some point you need to look at testing the business rules that your filter is shooting to meet.

testing your filter's business rules

When testing your business rules, its important to consider both expected and unexpected outcomes. For instance, here are two tests around the business rules that MyFilter is attempting to meet.

it('should show "no" when false is passed', inject(function ($filter, $log) {
    var myFilter = $filter('MyFilter');
    var result = myFilter(false);
    expect(result).toBe('no');
}));
it('should require a known argument value', inject(function ($filter, $log) {
    var myFilter = $filter('MyFilter');
    expect(myFilter.bind(this, null)).toThrow();
}));

The first test shows a test for an expected outcome. The second test shows a test for an unexpected outcome. The second test shows how to test for exceptions in Jasmine.

In review, first test that your filter is loaded. Once verified, you can turn your focus to the meat-and-potatoes of testing the business rules. This post showed you how to test filters in AngularJS. You can view the demo or download the code. If you found this post helpful, help the community, and share this post via Google Plus, LinkedIn, or Twitter. Thank you.


Comments

comments powered by Disqus

Chad Campbell
Chad Campbell

Chad is an independent software professional. He has been named a Microsoft MVP five times. His books have been translated into multiple languages and distributed worldwide. He holds a computer science degree from Purdue University, where he also studied psychology.

Chad has built sites, apps, frameworks, libraries, and platforms using Java, .NET, and Node. He's ran his own startups and has created software for Fortune 100 companies. In short, Chad knows how to create software. From ideation to delivery. From start-to-finish.


Follow Chad Online