Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

a

Package Overview
Dependencies
Maintainers
2
Versions
68
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

a

Mocking framework and test framework in compact when-style. With recursive test runner

  • 0.3.8
  • Source
  • npm
  • Socket score

Version published
Maintainers
2
Created
Source

a

Mocking framework + testing framework.

The mocking framework can be used in any JavaScript testing framework.

The testing framework has a short and concise bdd syntax - with reusable contexts.

how to install

npm install a

if you want the test framework, install it globally too

npm install a -g

Mocking

Mocking a function

partial mock

var original = function() {
	return 'realValue';
}

var mock = require('a').mock(original);
original = mock;
mock.expect().return('fake');

original(); //returns 'fake'
original(); //returns 'realValue'

strict mock

var mock = require('a').mock();
mock.expect().return('fake');

mock(); //returns 'fake'
mock(); //throws unexpected arguments

expecting arguments

var mock = require('a').mock();
mock.expect('testValue1').return('fake1');
mock.expect('testValue2').return('fake2');

mock('testValue1'); //returns 'fake1'
mock('testValue2'); //returns 'fake2'
mock(); //throws unexpected arguments
mock('foo'); //throws unexpected arguments

expecting multiple arguments

var mock = require('a').mock();
mock.expect('firstArg1', 'secondArg1').return('fake1');
mock.expect('firstArg2', 'secondArg2').return('fake2');


mock('firstArg1', 'secondArg1'); //returns 'fake1'
mock('firstArg2', 'secondArg2'); //returns 'fake2'
mock('foo'); //throws unexpected arguments
mock('foo', 'bar'); //throws unexpected arguments

expecting array

var mock = require('a').mock();
mock.expect(['a','b']).return('fake1');
mock.expect(['a','b').return('fake2');
mock.expect(['c','d').return('fake3');

mock(['a','b']); //returns 'fake1'
mock(['a','b']); //returns 'fake2'
mock(['c','d']); //returns 'fake3'
mock(['a','b']); //throws unexpected arguments
mock(['foo', 'bar']); //throws unexpected arguments

expecting struct

var mock = require('a').mock();
var obj = {};
mock.expect({a : 1}).return('fake1');
mock.expect({a : 2}).return('fake2');
mock.expect({a : 2, b : {c : 'foo', d : ['me', 'too']}}).return('fake3');
mock.expect(obj).return('fake4');
mock.expect({}).return('will never happen');

mock({a : 'x'}); //throws unexpected arguments
mock({a : 1}); //returns 'fake1'
mock({a : 2}); //returns 'fake2'
mock({a : 2, b : {c : 'foo', d : ['me', 'too']}}); //returns 'fake3'
mock(obj);  //returns 'fake3'
mock({});  //throws unexpected arguments

repeats

var mock = require('a').mock();
mock.expect().return('fake').repeat(2);

mock(); //returns 'fake'
mock(); //returns 'fake'
mock(); //throws unexpected arguments

infinite repeats

var mock = require('a').mock();
mock.expect().return('fake').repeatAny();

mock(); //returns 'fake'
mock(); //returns 'fake'
mock(); //returns 'fake'...

ignoring arguments

var mock = require('a').mock();
mock.expectAnything().return('fake1');

mock('someRandomValue'); //returns 'fake1'
mock(); //throws unexpected arguments

ignore alias

var mock = require('a').mock();
mock.ignore().return('fake1'); //same as expectAnything

mock('someRandomValue'); //returns 'fake1'
mock(); //throws unexpected arguments

throwing exceptions

var mock = require('a').mock();
var error = new Error('invalid operation');
mock.expect().throw(error);
mock.expect().return('fake');

mock(); //throws error
mock(); //returns 'fake'

intercepting

var mock = require('a').mock();
mock.expect('testValue').whenCalled(onCalled).return('fake1');

function onCalled(arg) {
	//arg == 'testValue'
}

mock('testValue'); //returns 'fake1'
mock(); //throws unexpected arguments

verify (fail)

var mock = require('a').mock();
mock.expect('testValue1').return('fake1');
mock.expect('testValue2').return('fake2');

mock('testValue1'); //returns 'fake1'
mock.verify(); //throws mock has 1 pending functions

verify (success)

var mock = require('a').mock();
mock.expect('testValue1').return('fake1');
mock.expect('testValue2').return('fake2');

mock('testValue1'); //returns 'fake1'
mock('testValue2'); //returns 'fake2'
mock.verify(); //returns true

returning void (compact syntax)

var mock = require('a').mock();
mock.expect('testValue1');
mock.expect('testValue2').repeat(2);

mock('testValue1'); //returns undefined
mock('testValue2'); //returns undefined
mock('testValue2'); //returns undefined
mock.verify(); //returns true

..is equivalent to ..

var mock = require('a').mock();
mock.expect('testValue1').return();
mock.expect('testValue2').return().repeat(2);

mock('testValue1'); //returns undefined
mock('testValue2'); //returns undefined
mock('testValue2'); //returns undefined
mock.verify(); //returns true

strict mock - advanced scenario

var mock = require('a').mock();
mock.expect('testValue').ignore().whenCalled(onCalled).return('fake1');

function onCalled(arg,callback) {
	//arg == 'testValue'
	//callback == foo
}

function foo() {	
}


mock('testValue', foo); //returns 'fake1'
mock.verify() //returns true
mock('testValue',foo); //throws unexpected arguments

Mocking require

expectRequire

var fakeDep = {};

var expectRequire = require('a').expectRequire;
expectRequire('./realDep').return(fakeDep);

require('./realDep'); //returns fakeDep
require('./realDep'); //returns realDep (behaves like a partial mock)

requireMock (compact syntax)

var requireMock = require('a').requireMock;
var fakeDep = requireMock('./realDep'); //returns a strict mock

require('./realDep'); //returns fakeDep
require('./realDep'); //returns realDep

..is equivalent to ..

var mock = require('a').mock();
var expectRequire = require('a').expectRequire;

var fakeDep = mock; 
expectRequire('./realDep').return(fakeDep);

require('./realDep'); //returns fakeDep
require('./realDep'); //returns realDep

Mocking an object

partial object mock

function newCustomer(_name) {
	var c = {};
	
	c.getName = function () 
	{
		return _name;
	};

	return c;
}

var customer = newCustomer('Alfonzo The Real');
var customerMock = mock(customer);

customerMock.getName.expect().return('Johnny Fake');

customer.getName(); //returns Johnny Fake
customer.getName(); //returns Alfonzo The Real
customerMock.verify(); //returns true

A test framework

A test framework is a simplistic, magic-free library providing unit-testing facilities with a compact, bdd-style syntax.

In contrast to other bdd-style test frameworks, however, it doesn't allow nesting suites in each other in order to test the SUT(subject under test) in different states. Instead, the framework relies on folder structure to describe the state which the SUT currently is. Suite names are generated based on their filenames. As a result there will be many small test files instead of few big ones with test suites nested in each other.

Test setup -- the "Arrange-Act" part of suites, is separated from the "Assert" part. This way the same setup can be used across different suites. Test setups can, of course, be chained.

Examples below can be found here: https://github.com/alfateam/a_demo

Example

The test runner ( when ) will search for all files named when*.js in current directory and below.

Given the following file structure

  • demo/
    • counter.js
    • counter_specs/
      • new/
        • increment.js
        • when_incremented.js
      • new.js
      • when_new.js

counter.js

module.exports = function () {
	var counter = {
		value: 0,
		increment: function() { value++; }
	};
	
	return counter;
}

counter_specs/new.js

function act(c) {
	var createCounter = require('../counter');
	c.sut = createCounter();
}
module.exports = act;

counter_specs/when_new.js

var c = {}; //test context object
var when = require('a').when;

when('./new', c). //set up
	it('should be an object').
		assertEqual('object', typeof c.sut)
	it('should have value equal to zero').
		assertEqual(0, c.sut.value).
	it('should fail just for fun').
		assertFail('error message');

counter_specs/new/increment.js

function act(c) {
	c.sut.increment();
}
act.base = '../new';
module.exports = act;

counter_specs/new/when_incremented.js

var c = {};
var when = require('a').when;

when('./increment', c).
	it('should have value equal to 1').
		assertEqual(1, c.sut.value);

In demo directory run when

user@localhost:~/a_demo $ when

 » counter_specs » new

  ✓ should be an object
  ✓ should have value equal to zero
  ✘ should fail just for fun

 » counter_specs » new » increment

  ✓ should have value equal to 1

========== Summary =============

counter_specs » new
  ✘ should fail just for fun

AssertionError: error message
	at retval.assertFail (/home/user/a_demo/node_modules/a/when/it.js:14:11)
	at Object.test (/home/user/a_demo/node_modules/a/when/test_invoker.js:5:3)
	at Object.retval.assertFail (/home/user/a_demo/node_modules/a/when/it.js:13:5)
	at Object.<anonymous> (/home/user/a_demo/counter_specs/when_new.js:11:3)
	at Module._compile (module.js:449:26)
	at Object.Module._extensions..js (module.js:467:10)
	at Module.load (module.js:356:32)
	at Function.Module._load (module.js:312:12)
	at Module.require (module.js:362:17)
	at require (module.js:378:17)
------------

suites: 2, passed: 3, failed: 1

Release Notes

0.3.8
Cleaner stack trace on mock errors.
0.3.7
Test path can be sent as argument to test runner.
If no path is specified, the test runner will run from current directory.
Example: when c:/devel/foo/testFolder
0.3.6
Exit code is equal to number of failing tests.
0.3.5
Tests files are run in hierarchical order from top to bottom.
0.3.4
Cache was cleared at wrong time. This could lead to overflow when running large amount of tests.
Make sure you update globally (npm update a -g) to get this fix, not only the local dependency.
0.3.3
Error in documentation about structs.
0.3.2
Mocks can be set up to throw.
0.3.1
"when" deletes all cached modules before executing. This ensures tests are isolated.
ignore is alias for expectAnything.
"When" can resolve act by camcelCase convention. If test class is named "whenFoo.js", it will assume "foo.js" is the act.

0.3.0
expectArray is deprecated, use expect instead.
expect now handles structs - equality is acheived when same propertyNames and equal leaf properties.

0.2.9
"When" can resolve act by convention. If test class is named "when_foo.js", it will assume "foo.js" is the act.
Example, given when_foo.js:

var c = {};
var when = require('a').when;

when(c). //equivalent to: when('./foo',c)....
	it('should have value equal to 1').
		assertEqual(1, c.sut.value);

Keywords

FAQs

Package last updated on 12 Dec 2013

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc