Top Related Projects
BDD / TDD assertion framework for node.js and the browser that can be paired with any testing framework.
Simple JavaScript testing framework for browsers and node.js
☕️ simple, flexible, fun javascript test framework for node.js & the browser
Additional Jest matchers 🃏💪
Write better assertions
Quick Overview
Should.js is a popular assertion library for Node.js and the browser. It provides expressive, readable assertions that extend the Object.prototype, allowing for a more natural language-like syntax in testing. Should.js is designed to work with various testing frameworks and can be used in both BDD and TDD styles.
Pros
- Highly expressive and readable syntax
- Extensive set of assertions for various data types
- Compatible with multiple testing frameworks
- Supports both Node.js and browser environments
Cons
- Extends Object.prototype, which may cause conflicts with other libraries
- Learning curve for developers used to traditional assertion libraries
- Some users may find the syntax too verbose for simple assertions
- Potential performance overhead due to the extensive use of getters and setters
Code Examples
- Basic assertion:
const should = require('should');
(5).should.be.exactly(5);
This example demonstrates a simple equality assertion using Should.js.
- Chaining assertions:
const user = { name: 'John', age: 30 };
user.should.have.property('name', 'John')
.and.have.property('age')
.which.is.a.Number()
.and.above(18);
This example shows how to chain multiple assertions for more complex validations.
- Asynchronous assertions:
const fs = require('fs').promises;
it('should read a file', async () => {
const content = await fs.readFile('test.txt', 'utf8');
content.should.startWith('Hello').and.endWith('world!');
});
This example demonstrates how to use Should.js with asynchronous operations.
Getting Started
To use Should.js in your project, follow these steps:
- Install Should.js using npm:
npm install --save-dev should
- In your test file, require Should.js:
const should = require('should');
- Start writing assertions in your tests:
describe('My Test Suite', () => {
it('should perform a simple assertion', () => {
const result = someFunction();
result.should.equal(expectedValue);
});
});
Now you can run your tests using your preferred test runner, such as Mocha or Jest.
Competitor Comparisons
BDD / TDD assertion framework for node.js and the browser that can be paired with any testing framework.
Pros of Chai
- Multiple assertion styles (expect, should, assert) offering flexibility
- Extensive plugin ecosystem for additional functionality
- Better TypeScript support and type definitions
Cons of Chai
- Slightly steeper learning curve due to multiple styles
- Potentially larger bundle size when using all assertion styles
Code Comparison
Chai (expect style):
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.lengthOf(3);
Should.js:
foo.should.be.a.String();
foo.should.equal('bar');
foo.should.have.length(3);
Key Differences
- Chai offers multiple assertion styles, while Should.js focuses on the 'should' style
- Chai has a larger community and more frequent updates
- Should.js has a slightly more natural language-like syntax
- Chai provides better browser support and compatibility
Use Cases
- Chai: Larger projects with diverse testing needs and multiple developers
- Should.js: Projects preferring a single, consistent assertion style
Community and Maintenance
- Chai: More active development, larger community, frequent updates
- Should.js: Smaller community, less frequent updates, but still maintained
Simple JavaScript testing framework for browsers and node.js
Pros of Jasmine
- More comprehensive testing framework with built-in test runner and reporting
- Wider adoption and larger community support
- Better suited for browser-based testing
Cons of Jasmine
- Steeper learning curve due to more extensive API
- Heavier and more opinionated, which may not suit all project types
- Less flexibility in assertion styles compared to Should.js
Code Comparison
Should.js:
const user = { name: 'John', age: 30 };
user.should.have.property('name', 'John');
user.age.should.be.above(18);
Jasmine:
describe('User', () => {
it('should have correct properties', () => {
const user = { name: 'John', age: 30 };
expect(user.name).toBe('John');
expect(user.age).toBeGreaterThan(18);
});
});
Summary
Should.js is a lightweight assertion library that extends Object.prototype, providing a more natural language-like syntax for assertions. It's flexible and can be used with various test runners.
Jasmine is a complete testing framework that includes a test runner, assertion library, and reporting tools. It's more suitable for larger projects and offers a structured approach to writing and organizing tests.
Choose Should.js for its simplicity and flexibility, especially when working with other test runners. Opt for Jasmine when you need a full-featured testing solution, particularly for browser-based applications.
☕️ simple, flexible, fun javascript test framework for node.js & the browser
Pros of Mocha
- More comprehensive testing framework with built-in test runner
- Supports various assertion libraries, including Should.js
- Offers a wide range of reporting options and plugins
Cons of Mocha
- Steeper learning curve due to more features and configuration options
- Requires additional setup for assertions (e.g., choosing and importing an assertion library)
Code Comparison
Mocha test example:
describe('Array', function() {
describe('#indexOf()', function() {
it('should return -1 when the value is not present', function() {
assert.equal([1, 2, 3].indexOf(4), -1);
});
});
});
Should.js assertion example:
[1, 2, 3].should.not.containEql(4);
Key Differences
- Mocha is a full-featured testing framework, while Should.js is primarily an assertion library
- Should.js focuses on providing expressive, readable assertions
- Mocha can be used with various assertion libraries, including Should.js
- Should.js can be used independently or integrated with other testing frameworks
Use Cases
- Choose Mocha for a complete testing solution with flexibility in assertion styles
- Opt for Should.js when you prefer its expressive, chainable assertion syntax
- Consider using both together: Mocha as the test runner and Should.js for assertions
Additional Jest matchers 🃏💪
Pros of jest-extended
- Seamless integration with Jest, a popular JavaScript testing framework
- Provides a wide range of additional matchers, enhancing Jest's functionality
- Actively maintained with regular updates and community support
Cons of jest-extended
- Limited to Jest ecosystem, not usable with other testing frameworks
- May have a steeper learning curve for developers new to Jest
- Potentially slower test execution due to additional matchers
Code Comparison
jest-extended:
expect(array).toBeArrayOfSize(3);
expect(value).toBeWithin(start, end);
expect(func).toThrowWithMessage(Error, 'Error message');
should.js:
array.should.have.length(3);
value.should.be.within(start, end);
(function() { func(); }).should.throw(Error, 'Error message');
Key Differences
- Syntax: jest-extended uses
expect()
assertions, while should.js uses a more natural language-like syntax - Framework dependency: jest-extended is specific to Jest, while should.js is framework-agnostic
- Extensibility: Both libraries allow for custom matchers, but jest-extended focuses on enhancing Jest's capabilities
Use Cases
- Choose jest-extended when working with Jest and needing additional matchers
- Opt for should.js when seeking a versatile assertion library for various testing frameworks or environments
Write better assertions
Pros of expect
- More flexible syntax with both
expect(value).toBe(expected)
andexpect(value).to.be(expected)
styles - Better support for asynchronous testing with
async/await
and Promises - Extensive plugin ecosystem for additional matchers and functionality
Cons of expect
- Slightly more verbose syntax for some assertions
- Less emphasis on chainable assertions compared to should.js
- May require additional configuration for certain testing frameworks
Code Comparison
expect:
expect(foo).toBe(true);
expect(bar).toEqual({ baz: 'qux' });
await expect(asyncFn()).resolves.toBe('result');
should.js:
foo.should.be.true();
bar.should.eql({ baz: 'qux' });
await asyncFn().should.eventually.equal('result');
Summary
Both expect and should.js are popular assertion libraries for JavaScript testing. expect offers more flexibility in syntax and better support for modern asynchronous testing patterns, while should.js provides a more fluent, chainable API. The choice between them often comes down to personal preference and specific project requirements. expect's plugin system and broader ecosystem may give it an edge for complex testing scenarios, but should.js's simpler syntax can be more intuitive for some developers.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
should.js
should is an expressive, readable, framework-agnostic assertion library. The main goals of this library are to be expressive and to be helpful. It keeps your test code clean, and your error messages helpful.
By default (when you require('should')
) should extends the Object.prototype
with a single non-enumerable getter that allows you to express how that object should behave. It also returns itself when required with require
.
It is also possible to use should.js without getter (it will not even try to extend Object.prototype), just require('should/as-function')
. Or if you already use version that auto add getter, you can call .noConflict
function.
Results of (something).should
getter and should(something)
in most situations are the same
Upgrading instructions
Please check wiki page for upgrading instructions.
FAQ
You can take look in FAQ.
Example
var should = require('should');
var user = {
name: 'tj'
, pets: ['tobi', 'loki', 'jane', 'bandit']
};
user.should.have.property('name', 'tj');
user.should.have.property('pets').with.lengthOf(4);
// If the object was created with Object.create(null)
// then it doesn't inherit `Object.prototype`, so it will not have `.should` getter
// so you can do:
should(user).have.property('name', 'tj');
// also you can test in that way for null's
should(null).not.be.ok();
someAsyncTask(foo, function(err, result){
should.not.exist(err);
should.exist(result);
result.bar.should.equal(foo);
});
To begin
-
Install it:
$ npm install should --save-dev
-
Require it and use:
var should = require('should'); (5).should.be.exactly(5).and.be.a.Number();
var should = require('should/as-function'); should(10).be.exactly(5).and.be.a.Number();
-
For TypeScript users:
import * as should from 'should'; (0).should.be.Number();
In browser
Well, even when browsers by complaints of authors have 100% es5 support, it does not mean it has no bugs. Please see wiki for known bugs.
If you want to use should in browser, use the should.js
file in the root of this repository, or build it yourself. To build a fresh version:
$ npm install
$ npm run browser
The script is exported to window.should
:
should(10).be.exactly(10)
You can easy install it with npm or bower:
npm install should -D
# or
bower install shouldjs/should.js
API docs
Actual api docs generated by jsdoc comments and available at http://shouldjs.github.io.
Usage examples
Please look on usage in examples
.not
.not
negates the current assertion.
.any
.any
allow for assertions with multiple parameters to assert any of the parameters (but not all). This is similar to the native JavaScript array.some.
Assertions
chaining assertions
Every assertion will return a should.js
-wrapped Object, so assertions can be chained.
To help chained assertions read more clearly, you can use the following helpers anywhere in your chain: .an
, .of
, .a
, .and
, .be
, .have
, .with
, .is
, .which
. Use them for better readability; they do nothing at all.
For example:
user.should.be.an.instanceOf(Object).and.have.property('name', 'tj');
user.pets.should.be.instanceof(Array).and.have.lengthOf(4);
Almost all assertions return the same object - so you can easy chain them. But some (eg: .length
and .property
) move the assertion object to a property value, so be careful.
Adding own assertions
Adding own assertion is pretty easy. You need to call should.Assertion.add
function. It accept 2 arguments:
- name of assertion method (string)
- assertion function (function)
What assertion function should do. It should check only positive case. should
will handle .not
itself.
this
in assertion function will be instance of should.Assertion
and you must define in any way this.params object
in your assertion function call before assertion check happen.
params
object can contain several fields:
operator
- it is string which describe your assertionactual
it is actual value, you can assume it is your own this.obj if you need to define you ownexpected
it is any value that expected to be matched this.obj
You can assume its usage in generating AssertionError message like: expected obj
? || this.obj not? operator
expected
?
In should
sources appeared 2 kinds of usage of this method.
First not preferred and used only for shortcuts to other assertions, e.g how .should.be.true()
defined:
Assertion.add('true', function() {
this.is.exactly(true);
});
There you can see that assertion function do not define own this.params
and instead call within the same assertion .exactly
that will fill this.params
. You should use this way very carefully, but you can use it.
Second way preferred and i assume you will use it instead of first.
Assertion.add('true', function() {
this.params = { operator: 'to be true', expected: true };
should(this.obj).be.exactly(true);
});
in this case this.params defined and then used new assertion context (because called .should
). Internally this way does not
create any edge cases as first.
Assertion.add('asset', function() {
this.params = { operator: 'to be asset' };
this.obj.should.have.property('id').which.is.a.Number();
this.obj.should.have.property('path');
})
//then
> ({ id: '10' }).should.be.an.asset();
AssertionError: expected { id: '10' } to be asset
expected '10' to be a number
> ({ id: 10 }).should.be.an.asset();
AssertionError: expected { id: 10 } to be asset
expected { id: 10 } to have property path
Additional projects
should-sinon
- adds additional assertions for sinon.jsshould-immutable
- extends different parts of should.js to make immutable.js first-class citizen in should.jsshould-http
- adds small assertions for assertion on http responses for node onlyshould-jq
- assertions for jq (need maintainer)karma-should
- make more or less easy to work karma with should.jsshould-spies
- small and dirty simple zero dependencies spies
Contributions
Actual list of contributors if you want to show it your friends.
To run the tests for should simply run:
$ npm test
See also CONTRIBUTING.
OMG IT EXTENDS OBJECT???!?!@
Yes, yes it does, with a single getter should, and no it won't break your code, because it does this properly with a non-enumerable property.
Also it is possible use it without extension. Just use require('should/as-function')
everywhere.
License
MIT. See LICENSE for details.
Top Related Projects
BDD / TDD assertion framework for node.js and the browser that can be paired with any testing framework.
Simple JavaScript testing framework for browsers and node.js
☕️ simple, flexible, fun javascript test framework for node.js & the browser
Additional Jest matchers 🃏💪
Write better assertions
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot