Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Mocking framework and test framework in compact when-style. With recursive test runner
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
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 original = function() {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expect().return('fake');
original(); //returns 'fake'
original(); //throws unexpected arguments
strict mock with arguments
var original = function(arg) {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expect('testValue1').return('fake1');
mock.expect('testValue2').return('fake2');
original('testValue1'); //returns 'fake1'
original('testValue2'); //returns 'fake2'
original(); //throws unexpected arguments
original('foo'); //throws unexpected arguments
strict mock with multiple arguments
var original = function(arg1, arg2) {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expect('firstArg1', 'secondArg1').return('fake1');
mock.expect('firstArg2', 'secondArg2').return('fake2');
original('firstArg1', 'secondArg1'); //returns 'fake1'
original('firstArg2', 'secondArg2'); //returns 'fake2'
original('foo'); //throws unexpected arguments
original('foo', 'bar'); //throws unexpected arguments
strict mock expecting array
var original = function(array) {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expectArray(['a','b']).return('fake1');
mock.expectArray(['a','b').return('fake2');
mock.expectArray(['c','d').return('fake3');
original(['a','b']); //returns 'fake1'
original(['a','b']); //returns 'fake2'
original(['c','d']); //returns 'fake3'
original(['a','b']); //throws unexpected arguments
original(['foo', 'bar']); //throws unexpected arguments
strict mock with repeats
var original = function() {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expect().return('fake').repeat(2);
original(); //returns 'fake'
original(); //returns 'fake'
original(); //throws unexpected arguments
strict mock with infinite repeats
var original = function() {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expect().return('fake').repeatAny();
original(); //returns 'fake'
original(); //returns 'fake'
original(); //returns 'fake'...
strict mock ignoring arguments
var original = function(arg) {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expectAnything().return('fake1');
original('someRandomValue'); //returns 'fake1'
original(); //throws unexpected arguments
strict mock with interceptor
var original = function(arg) {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expect('testValue').whenCalled(onCalled).return('fake1');
function onCalled(arg) {
//arg == 'testValue'
}
original('testValue'); //returns 'fake1'
original(); //throws unexpected arguments
strict mock - verify (fail)
var original = function(arg) {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expect('testValue1').return('fake1');
mock.expect('testValue2').return('fake2');
original('testValue1'); //returns 'fake1'
mock.verify(); //throws mock has 1 pending functions
strict mock - verify (success)
var original = function(arg) {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expect('testValue1').return('fake1');
mock.expect('testValue2').return('fake2');
original('testValue1'); //returns 'fake1'
original('testValue2'); //returns 'fake2'
mock.verify(); //returns true
strict mock - advanced scenario
var original = function(arg, callback) {
return 'realValue';
}
var mock = require('a').mock();
original = mock;
mock.expect('testValue').expectAnything().whenCalled(onCalled).return('fake1');
function onCalled(arg,callback) {
//arg == 'testValue'
//callback == foo
}
function foo() {
}
original('testValue', foo); //returns 'fake1'
mock.verify() //returns true
original('testValue',foo); //throws unexpected arguments
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
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 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
The test runner ( when ) will search for all files named when*.js in current directory and below.
Given the following file structure
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
FAQs
Mocking framework
We found that a demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
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.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.