npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

jasmine-as-promised

v0.0.8

Published

Extensions to Jasmine unit testing to transparently support Promises in async testing scenarios

Downloads

61

Readme

Promise-Returning Tests for Jasmine

So you really like Jasmine. But you also really like promises. And you'd like to see support in Jasmine for the promise-returning test style; similar to the great work by Domenic Denicola for the Mocha as Promised and others.

This library provides an extension of the Jasmine Spec::runs() to support Promises and will auto-magically wait for the promise to resolve or reject before continuing with subsequent unit tests.

Best of all... it supports AngularJS and will signficantly reduce the size of your test code (see bottom).

The Old Way

Until now you've been making do with manual solutions that explicity use runs() and waitsFor() to force the test runner to pause the tests while waiting for the async response.

Here is a sample of code constructed in the tradition, old way. For purposes of code samples, let's consider API tests where the authors.validate() is asynchronous and returns a promise instance:

it( "should respond successfully for valid authors", function () {
	var ready  = false,
		result;
		
		runs( function() 
		{
			authors
			    .validate("Domenic Denicola")
			    .then(
			    	function onResponse( data )
			    	{
			    		result = data;
			    		ready  = true;		// continue test runner
			    	},
			    	function onError( fault )
			    	{
			    		ready  = true;		// continue test runner
			    	}
			    );
		});

		// Pause test runner until timeout or yourAsyncCall() responds		
		waitsFor( function() 
		{
			return result;
		});
		
		
		// Run the code that checks the expectations…
		
		runs( function() 
		{
			expect( result.valid ).toBeEqual( 1 );
			expect( result.level ).toBeEqual( "awesome" );
		});	    
});

Developers will immediately note that this traditional approach is verbose and error-prone when developers are need to create many tests for their async APIs.

The New, Better Solution

With Jasmine-As-Promised and APIs that return promises, consider the code tersity and simplicity that can be realized when your unit tests return Promises:

it( "should be respond for valid authors", function () 
{
	runs( function() 
	{    	
		return authenticator
			.validate("Domenic Denicola" )
			.then( function (result) 
			{
				expect( result.valid ).toBeEqual( 1 );
				expect( result.level ).toBeEqual( "awesome" );
			});
	});
});

You could even separate your expect() calls if wanted. Instead of nesting your expectations inside the promise handler, consider another supported approach:

it( "should respond successfully for valid authors", function () 
{
	runs( 
		function() 
		{    	
			return authenticator.validate("Domenic Denicola" );
		},
		function checkExpectations( result ) 
		{
			expect( result.valid ).toBeEqual( 1 );
			expect( result.level ).toBeEqual( "awesome" );
		}
	);
});

With this new approach developers no longer need to worry about waitsFor(), latch methods, etc. With Jasmine as Promised, you have a much two (2) much nicer, easily applied options available!

How to Use

Once you install and set up Jasmine-as-Promised, you now have a second way of creating asynchronous tests, besides Jasmine's usual runs(); waitsFor(); runs(); style. Just return a promise. When the promise is resolved the test expectations are checked and if it is rejected the test fails, with the rejection reason as the error. Nice, huh?

Jasmine as Promised works with all Jasmine interfaces: BDD, TDD, QUnit, whatever. It hooks in at such a low level, the interfaces don't even get involved.

This is NOT Jasmine-Node

Jasmine-Node is a project that integrates the Jasmine Spec framework with NodeJS.

jasmine-node includes an alternate syntax for writing asynchronous tests. Accepting a done callback in the specification will trigger jasmine-node to run the test asynchronously waiting until the done() callback is called.

var request = require('request');

it("should respond with hello world", function(done) {
  request("http://localhost:3000/hello", function(error, response, body){
    expect(body).toEqual("hello world");
    done();
  });
});

Notice that this Jasmine-as-Promised library does not use a done callback function argument in the it( ) call. But developers can still use Jasmine-As-Promised with Jasmine-Node; see the usage notes below for use with Node.

Installation and Usage

Node

Do an npm install jasmine-as-promised --save-dev to get up and running. Then:

require("jasmine-as-promised")();

You can of course put this code in a common test fixture file; for an example, see the Jasmine as Promised tests.

AMD

Jasmine-as-Promised supports being used as an AMD module, registering itself anonymously. So, assuming you have configured your loader to map the Jasmine and Jasmine as Promised files to the respective module IDs "jasmine" and "jasmine-as-promised", you can use them as follows:

define(function (require, exports, module) {
    var jasmine = require("jasmine");
    var jasmineAsPromised = require("jasmine-as-promised");

    jasmineAsPromised(jasmine);
});

<script> tag

If you include Jasmine-as-Promised directly with a <script> tag, after the one for Jasmine itself, then it will automatically plug in to Jasmine and be ready for use:


<script src="jasmine"></script>
<script src="jasmine-as-promised.js"></script>

Node, the Advanced Version

The require("jasmine-as-promised")() above tries to detect which instance of Jasmine is being used automatically. This way, Jasmine-as-Promised can plug into either the local Jasmine instance installed into your project, or into the global Jasmine instance if you're running your tests using the globally-installed command-line runner.

In some cases, if you're doing something weird, this can fall down. In these cases, you can pass the Jasmine instance into into the Jasmine-as-Promised function. For example, if you somehow had your Jasmine module as a property of the foo module, instead of it being found in the usual npm directory structures, you would do

require("jasmine-as-promised")(require("foo").MyJasmine);

Bower, the Package Manager

Now you can use Bower (the package manager for the web) to get the most recent released version of the library installed in your project-relative bower_components directory.

bower install jasmine-as-promised

And Bower will also auto-install the Jasmine library for you; as part of this library install.

How Does This Work!?

While this approach using the interceptor or head hook approach, it should be note that this is hack... albeit a reasonable one. Note that Jasmine-as-Promised just overrides the window.runs method (published as part of Jasmine core); check the source for more details.

Using with AngularJS

When using AngularJS with Jasmine Specs (and Jasmine-as-Promised ), developers have two (2) types of test scenarios:

  • Testing with angular-mocks to use mock $http and mock $timeout(s).
  • Testing with angular-spec to use Jasmine tests with LIVE $http (real XHR) calls.

Developers should study the test Specs prepared within test_withAngular.html. That file shows you how:

  • script libraries should be loaded (for tests)
  • Jasmine should be started
  • angular services can be constructed with mock APIs
  • Spec(s) can be implemented using inject( ) and runs( )
  • Angular Promise-based services can be easily tested.

Using RequireJS

Developers should note that these do NOT show how RequireJS can also be used… that is out-of-scope for this project. If you really need to know how to use RequireJS with your tests and Karma, contact me or come and see me at the 2014 NG-Conference