Click here to Skip to main content
14,116,173 members
Click here to Skip to main content
Add your own
alternative version

Stats

21K views
4 bookmarked
Posted 14 Feb 2016
Licenced CPOL

promise-sync - Synchronous Promise for Making Testing Experience Much Easier

, 16 Apr 2016
Rate this:
Please Sign up or sign in to vote.
Synchronous promise for making testing experience much easier

Introduction

  • Did you ever need to use setTimeout just to make sure the async logic happened before you test the result?
  • Do your tests run slowly because of long waits for async results?
  • Have you ever tried to make a race condition test of 2 promises?
  • Do you want to control the exact moment the promise resolves or rejects?

Well, it all happened to me, so I searched for a library to make all of these work as I want. All the results had a few things missing, some were async, some didn't have the chaining, some threw errors if you didn't subscribe to them.

So I decided to write a new one.

Features

  • Support callback subscription: success(), catch(), then(), finally()
  • Chaining callback subscriptions
  • Support state checking: state, isPending(), isRejected(), isFulfilled()
  • Support resolving and rejecting: resolve(data?), reject(reason?)
  • Make it possible to ignore assertion errors inside the success/failure/finally callbacks
  • Create a resolved/rejected promise with one simple line
  • Wait for all promises to resolve using PromiseMock.all() method
  • Wait for one of the promises to resolve using PromiseMock.race() method
  • Written in Typescript so its type-safe
  • Resolving or rejecting not pending promise will throw error
  • Subscribing to resolved promise will raise proper callbacks
  • Subscribing to rejected promise will raise proper callbacks
  • Synchronous!

Using the Code

Installation

 npm install promise-sync --save-dev

Typescript

import { PromiseMock, PromiseState } from 'promise-sync';

var promiseMock = new PromiseMock<number>();

var onSuccessCallback = () => console.log('success');
var onFailureCallback = () => console.log('failure');
var finallyCallback = () => console.log('finally');

promiseMock.then(onSuccessCallback, onFailureCallback)
           .success(onSuccessCallback)
           .catch(onFailureCallback)
           .finally(finallyCallback);

var dataToResolve = 123;
promiseMock.resolve(dataToResolve);

var errorToReject = 'some error';
promiseMock.reject(errorToReject);

var isPending = promiseMock.isPending();
var isFulfilled = promiseMock.isFulfilled();
var isRejected = promiseMock.isRejected();

var state: PromiseState = promiseMock.state;

var rejectedPromise: PromiseMock<string> = PromiseMock.reject('some error');
var resolvedPromise: PromiseMock<string> = PromiseMock.resolve('some data');

var waitForAll: PromiseMock<any[]> = PromoseMock.all(
  [
    rejectedPromise,
    resolvedPromise,
    'random data that will be converted to resolved promise'
  ]);

var waitForFirst: PromiseMock<any> = PromoseMock.race(
  [
    rejectedPromise,
    resolvedPromise,
    'random data that will be converted to resolved promise'
  ]);

JavaScript

var promise_sync = require('promise-sync');
var PromiseMock = promise_sync.PromiseMock;
var PromiseState = promise_sync.PromiseState;

var promiseMock = new PromiseMock();

var onSuccessCallback = function() { console.log('success'); }
var onFailureCallback = function() { console.log('failure'); }
var finallyCallback = function() { console.log('finally'); }

promiseMock.then(onSuccessCallback, onFailureCallback)
           .success(onSuccessCallback)
           .catch(onFailureCallback)
           .finally(finallyCallback);

var dataToResolve = 123;
promiseMock.resolve(dataToResolve);

var errorToReject = 'some error';
promiseMock.reject(errorToReject);

var isPending = promiseMock.isPending();
var isFulfilled = promiseMock.isFulfilled();
var isRejected = promiseMock.isRejected();

var state = promiseMock.state;

var rejectedPromise = PromiseMock.reject('some error');
var resolvedPromise = PromiseMock.resolve('some data');

var waitForAll = PromoseMock.all(
  [
    rejectedPromise,
    resolvedPromise,
    'random data that will be converted to resolved promise'
  ]);

var waitForFirst = PromoseMock.race(
  [
    rejectedPromise,
    resolvedPromise,
    'random data that will be converted to resolved promise'
  ]);

Be Aware!

The methods: 'then/success/catch/finally' catch exceptions thrown in the callbacks. So if you want to do assertions inside of them, you need to tell the PromiseMock to ignore assertion error exceptions, otherwise the tests will pass even though the assertions are failing.

If you are using chai for example:

Typescript

import { AssertionError } from 'chai';
import { PromiseMock } from 'promise-sync';

PromiseMock.setAssertionExceptionTypes([AssertionError]);

Same Example using JavaScript

var chai = require('chai');
var promise_sync = require('promise-sync');
var PromiseMock = promise_sync.PromiseMock;

PromiseMock.setAssertionExceptionTypes([chai.AssertionError]);

Updates

17/02/2016 (version 0.1.7)

  • Updated the npm package to include only the essential files: *.js, *.d.ts files

05/03/2016 (version 0.1.91)

  • Added the PromiseMock.setAssertionExceptionTypes method to allow ignoring asserion errors inside the success/failure/finally callbacks.
  • Also fixed a bug when rejecting and then registering will not pass the rejected error

06/03/2016 (version 1.0.0)

  • Added support for static builder methods: PromiseMock.resolve('data'), PromiseMock.reject('error')
  • Added support to wait for multiple promises to resolve: PromiseMock.all(promises)
  • Added support to wait for first promise to resolve: PromiseMock.race(promises)

21/03/2016 (version 1.1.0)

  • Fixed a bug when returning a promise from success/failure callbacks, should propagate the value of the returned promise and not the value given as an argument to the callback (Issue #5)

11/04/2016 (version 1.1.1)

  • Fixed a bug when chaining then statements with real promises returned from the callbacks. (Issue #7)

14/04/2016 (version 1.1.3)

  • Remove the readonly from the state property to support older versions of typescript
  • Added public License file

16/04/2016 (version 1.1.4)

  • Fix a bug: rejectedPromose.success().catch() was not calling the failure callback in the catch method

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

slavik57
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01 | 2.8.190518.1 | Last Updated 16 Apr 2016
Article Copyright 2016 by slavik57
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid