Shaken, not Stirred – Using Spies in Jasmine



Shaken, not Stirred – Using Spies in Jasmine

0 0


jasmine-spies-slides

Jasmine Spies Lightning Talk

On Github daniellecloss / jasmine-spies-slides

Shaken, not Stirred

Using Spies in Jasmine

Created by Danielle Closs / @daniellecloss
1 of 14 Hello! I'm Danielle. I am a UI Web developer at Arbor Networks. Sometimes I spy on my Javascript code, occassionally with a drink in hand, using Jasmine Spies.

What is aJasmine Spy?

2 of 14 So, you may be wondering what a Jasmine Spy is, or for that matter, what Jasmine is. Jasmine is a testing framework for Javascript....

A Jasmine Spy Function is...

...just another function, written inside a Jasmine test.

It is generally written to "mock" an existing function, so that you control the function implementation.

3 of 14 ....and a Jasmine Spy function is basically a mock function, also known as a test double function, that can be used in place of an actual function in your code. Generally speaking, you want to use Jasmine Spies when you want more control over your testing implementation.

This is a Jasmine Spy Function

Spy.modify_secret = function() {
  var secret = Spy.tell_secret();
  Spy.secret = secret + " either";
};
spyOn(Spy, 'modify_secret');

The key is the spyOn() method, the rest is just javascript!

4 of 14 This is what a basic Jasmine Spy function looks like. It's really just a javascript function, that you can easily control, which mimicks a function from your code. It's a "copy" of that function that you have control of. Then you can spy on that function, as well as the actual functions that you are testing.

In the beforeEach() Block

beforeEach(function() {
   Spy.modify_secret = function() {
      var secret = Spy.tell_secret();
      Spy.secret = secret + " either";
   };
   spyOn(Spy, 'modify_secret').and.callThrough();
});

the Spy is now accessible before each test

5 of 14 A Jasmine Spy function can be placed in a beforeEach() block. When the function is put in a beforeEach() block, it is accessible to each test in that test suite.

Create Assertions with Matchers

it("tracks that the spy was called", function() {
   expect(Spy.modify_secret).toHaveBeenCalled();
});

the Spy can be tested, like any other function

6 of 14 After you create a Jasmine Spy function, and spy on it, you can treat it like any other function in your test, and create assertions for it. Jasmine Spies have special matchers, like this one, toHaveBeenCalled(). All this matcher does is verify that the function has been called at least one time.

Using

.and.callThrough()

spyOn(Spy, 'modify_secret').and.callThrough();

to follow through on the function call(delegate to the actual implementation)

7 of 14 While I was creating this sample code, I ran into an issue where my tests were failing, because chained functions past the first function were not being called. The and.callThrough() method allows a chain of functions to fully complete their code execution. If you don't use this method and you have chained function execution, the code will stop processing, and your tests will fail.

Using

.and.returnValue()

spyOn(Spy, 'modify_secret').and.returnValue();

to always return the same value from this spy

8 of 14 Another useful method to use with your Jasmine Spies is and.returnValue(). This is another method that allows more control over the spy, by allowing you to always return the same value from your spy.

Use Cases

  • mock an API call, if you don’t want to directly call your API during test running, and want more control over the returned data
  • mock whole libraries (like jQuery), which is useful when testing functionality tied to browser interactivity
9 of 14 Some common use cases for using Jasmine Spies are: - mocking an api call, which you want to have consistent return data from - mocking jQuery functions, to test event handlers, like button clicks

More Jasmine Spy Features

The .calls() property

  • .calls.allArgs() - returns arguments to all calls
  • .calls.all() - returns context and arguments passed to all calls
  • .calls.mostRecent() - returns context and arguments for the most recent call
  • .calls.first() - returns context and arguments for the first call
10 of 14 Another popular feature of Jasmine Spies is the .calls property, which stores different types of information for the spies that are being used in your tests. This information has to do with returning the context and arguments for all spy calls or specific spy calls.

More Jasmine Spy Features

Other Spy Methods

  • .and.callFake() - all calls to the spy will delegate to a supplied function
  • .and.throwError() - all calls to the spy will throw the supplied error
  • .and.createSpy() - create a generic “bare" spy
11 of 14 Here are some other Jasmine Spy methods that are useful. - callFake, which is a way to stub a new function on the fly - throwError, which will throw a specific error that you supply - createSpy, which creates a generic, empty spy implementation

All Code Examples at

Github

github.com/daniellecloss/jasmine-spies-code-sample

var Spy = require('../jasmine-spies.js');

describe("A spy", function() {
  var fetched_secret, secret;

  beforeEach(function() {
    Spy.modify_secret = function() {
      var secret = Spy.tell_secret();
      ...
12 of 14 I have the code I used for these examples hosted at my github account, if you want to take a closer look. In the repo, there is an object in one file (the code), and three tests and a mocked function, used with a Jasmine Spy, in the test spec. You can install Jasmine, download the repo into a local folder, and just type Jasmine at the command line to run the tests.

For More Information

Jasmine Spies Documentation

All examples were using Jasmine 2.0 syntax, which has been updated from older versions of Jasmine

13 of 14 All of these examples were using Jasmine 2.0. Just an FYI, there were some specific syntax updates for Jasmine Spies in Jasmine version 2.0.
13 of 14 Thanks for listening, and I hope I have been able to give you a quick taste of what it's like to use Jasmine Spies, so that you are thirsty for more :)
Shaken, not Stirred Using Spies in Jasmine Created by Danielle Closs / @daniellecloss 1 of 14 Hello! I'm Danielle. I am a UI Web developer at Arbor Networks. Sometimes I spy on my Javascript code, occassionally with a drink in hand, using Jasmine Spies.