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

mockt

v0.8.2

Published

Joyful mocking library for Typescript and Javascript

Downloads

240

Readme

npm License: MIT CI Status

Getting Started

Npm:

$ npm install --save-dev mockt

Yarn:

$ yarn add -D mockt

Now let's write a simple test:

const calculator = mockt(Calculator)
when(calculator).sum(2, any()).returns(3)

const actual = calculator.sum(2, 8)

expect(actual).toEqual(3)
verify(calculator).sum(any(), 8)

Features

  • Typescript Support and IDE Autocompletion
  • Class mocks
  • Abstract class mocks
  • Interface mocks
  • Generics support
  • Flexible stubbing with multiple returns, custom function call, errors, promises and stub overriding.
  • Properties stubbing
  • Spy on real objects
  • Argument Capturing
  • Verification atLeast, atMost, once, times(n)
  • Verification called and never called
  • Properties read and write verification
  • Verification order
  • Argument Matchers for stubs and verifications
  • Reset mock stubs
  • Reset mock recorded calls

Table of Contents

Usage

Class mocks

class Calculator {
    sum(a: number, b: number): number {
        return a + b
    }
}

const calculator = mockt(Calculator)
when(calculator).sum(2, 3).returns(5)

calculator.sum(2, 3) // returns 5

Arrow methods

class Calculator {
    sum = (a: number, b: number) => a + b
}

const calculator = mockt(Calculator)
when(calculator).sum(2, 3).returns(5)

calculator.sum(2, 3) // returns 5

Note: arrow methods fails when called without stubbing them.

Abstract Class mocks

abstract class Calculator {
    abstract sum(a: number, b: number): number
}

const calculator = mockt(Calculator)
when(calculator).sum(2, 3).returns(5)

calculator.sum(2, 3) // returns 5

Note: abstract methods fails when called without stubbing them.

Interface mocks

interface Calculator {
    sum(a: number, b: number): number
}

const calculator = mockt<Calculator>()
when(calculator).sum(2, 3).returns(5)

calculator.sum(2, 3) // returns 5

Note: Interfaces are passed as Generic Parameter to mockt function.

Note: Interface methods fails when called without stubbing them.

Generics

interface List<T> {
    add(item: T): void
    get(index: number): T
}

const list = mockt(List<string>)
when(list).get(3).returns('Item 3')

list.get(3) // returns 'Item 3'

Properties

class User {
    public name: string
}

const user = mockt(User)
when(user).name.returns('Alice')

user.name // returns 'Alice'

Getters

class User {
    private _name: string
    
    get name(): string {
        return this._name
    }
}

const user = mockt(User)
when(user).name.returns('Alice')

user.name // returns 'Alice'

Stubbing

Multiple returns

const calculator = mockt(Calculator)
when(calculator).sum(2, 3).returns(5, 6, 7)

calculator.sum(2, 3) // returns 5
calculator.sum(2, 3) // returns 6
calculator.sum(2, 3) // returns 7
calculator.sum(2, 3) // returns 7

Stub overriding

const calculator = mockt(Calculator)
when(calculator).sum(2, 3).returns(5)
when(calculator).sum(2, 3).returns(6)

calculator.sum(2, 3) // returns 6
calculator.sum(2, 3) // returns 6
const calculator = mockt(Calculator)
when(calculator).sum(any(), any()).returns(5, 6)
when(calculator).sum(2, 3).returns(7)

calculator.sum(2, 3) // returns 7
calculator.sum(2, 4) // returns 5
calculator.sum(2, 5) // returns 6

Function call

const calculator = mockt(Calculator)
when(calculator).sum(any(), any()).calls((a, b) => a * b)

calculator.sum(2, 3) // returns 6
calculator.sum(3, 4) // returns 12

Throw error

const calculator = mockt(Calculator)
when(calculator).sum(any(), any()).throws(new Error('Some error'))

calculator.sum(2, 3) // throws Error('Some error')

Promise resolve

const apiClient = mockt(ApiClient)
when(apiClient).getUser().resolves(user1, user2)

await apiClient.getUser() // returns user 1
await apiClient.getUser() // returns user 2

Promise reject

const apiClient = mockt(ApiClient)
when(apiClient).getUser().rejects(new Error('Some error'))

await apiClient.getUser() // throws Error('Some error')

Chained answers

const calculator = mockt(Calculator)
when(calculator).sum(2, 3)
        .returns(5)
        .returns(6)
        .calls(() => 7)
        .throws(new Error('Some error'))

calculator.sum(2, 3) // returns 5
calculator.sum(2, 3) // returns 6
calculator.sum(2, 3) // returns 7
calculator.sum(2, 3) // throws Error('Some error')

Matchers

Equals

const calculator = mockt(Calculator)
when(calculator).sum(2, eq(3)).returns(5)

calculator.sum(2, 3) // returns 5
calculator.sum(2, 4) // returns undefined

Note: When a value is given instead of a matcher, the equals matcher is used. Note: Performs deep equality

Deep equality and type conversion
const billingService = mockt(BillingService)
when(billingService).calculateFor(eq({ user: { age: '17' } })).returns(100)

billingService.calculateFor({ user: { age: 17 } }) // returns 100

Not Equals

const calculator = mockt(Calculator)
when(calculator).sum(2, neq(3)).returns(5)

calculator.sum(2, 6) // returns 5
calculator.sum(2, 3) // returns undefined

Identical

const billingService = mockt(BillingService)
const alice = { name: 'Alice' }
when(billingService).calculateFor(is(alice)).returns(100)

billingService.calculateFor(alice) // returns 100
billingService.calculateFor({ name: 'Alice' }) // returns undefined

Any

const calculator = mockt(Calculator)
when(calculator).sum(2, any()).returns(5)

calculator.sum(2, 5) // returns 5
calculator.sum(2, 6) // returns 5
calculator.sum(3, 5) // returns undefined

Any Number

const calculator = mockt(Calculator)
when(calculator).sum(anyNumber(), any()).returns(5)

calculator.sum(1, 2) // returns 10
calculator.sum('1', 2) // returns undefined
calculator.sum(1, '2') // returns 10

Any String

const splitter = mockt(StringSplitter)
when(splitter).split(anyString()).returns(['Hello', 'World'])

splitter.split('Hello World') // returns ['Hello', 'World']
splitter.split('Bye') // returns ['Hello', 'World']
splitter.split(3) // returns undefined

Any Array

const calculator = mockt(Calculator)
when(calculator).average(anyArray()).returns(10)

calculator.average([1, 2]) // returns 10
calculator.average([3, 4]) // returns 10
calculator.average([]) // returns 10
calculator.average(3) // returns undefined

Any Object

const billingService = mockt(BillingService)
when(billingService).calculateFor(anyObject()).returns(2000)

billingService.calculateFor({ name: 'Alice', lastname: 'Jones' }) // returns 2000
billingService.calculateFor({}) // returns 2000
billingService.calculateFor('alice') // returns undefined

Any Function

const caller = mockt(FunctionCalled)
when(caller).call(anyFunction()).returns(10)

caller.call(() => {}) // returns 10
caller.call(function () {}) // returns 10
caller.call('alice') // returns undefined

IsNull

const billingService = mockt(BillingService)
when(billingService).calculateFor(isNull()).throws(new Error('User cannot be null'))

billingService.calculateFor(null) // throws Error('User cannot be null')
billingService.calculateFor({ name: 'Alice' }) // Doesn't throw
billingService.calculateFor(undefined) // Doesn't throw
billingService.calculateFor('') // Doesn't throw
billingService.calculateFor([]) // Doesn't throw

IsNil

const billingService = mockt(BillingService)
when(billingService).calculateFor(isNil()).throws(new Error('User cannot be null'))

billingService.calculateFor(null) // throws Error('User cannot be null')
billingService.calculateFor(undefined) // throws Error('User cannot be null')
billingService.calculateFor({ name: 'Alice' }) // Doesn't throw
billingService.calculateFor('') // Doesn't throw
billingService.calculateFor([]) // Doesn't throw

NotNull

const billingService = mockt(BillingService)
when(billingService).calculateFor(notNull()).returns(5000)

billingService.calculateFor({ name: 'Alice' }) // returns 5000
billingService.calculateFor(undefined) // returns 5000
billingService.calculateFor(null) // returns undefined

NotNil

const billingService = mockt(BillingService)
when(billingService).calculateFor(notNil()).returns(5000)

billingService.calculateFor({ name: 'Alice' }) // returns 5000
billingService.calculateFor(undefined) // returns undefined
billingService.calculateFor(null) // returns undefined

Less

const calculator = mockt(Calculator)
when(calculator).sum(less(5), any()).returns(10)

calculator.sum(4, 2) // returns 10
calculator.sum(5, 2) // returns 10
calculator.sum(6, 2) // returns undefined

More

const calculator = mockt(Calculator)
when(calculator).sum(more(5), any()).returns(10)

calculator.sum(6, 2) // returns 10
calculator.sum(5, 2) // returns 10
calculator.sum(4, 2) // returns undefined

Range

const calculator = mockt(Calculator)
when(calculator).sum(range(5, 10), any()).returns(10)

calculator.sum(4, 2) // returns undefined
calculator.sum(5, 2) // returns 10
calculator.sum(6, 2) // returns 10
calculator.sum(9, 2) // returns 10
calculator.sum(10, 2) // returns 10
calculator.sum(11, 2) // returns undefined

OfClass

const billingService = mockt(BillingService)
when(billingService).calculateFor(ofClass(Employee)).returns(2000)

billingService.calculateFor(new Employee('Alice')) // returns 2000
billingService.calculateFor(new User('Alice')) // returns undefined

Nested matchers

const billingService = mockt(BillingService)
when(billingService).calculateFor(eq({ name: 'Alice', lastname: any() })).returns(2000)

billingService.calculateFor({ name: 'Alice', lastname: 'Jones' }) // returns 2000
const calculator = mockt(Calculator)
when(calculator).average(eq([1, any(), 3])).returns(1)

calculator.average([1, 2, 3]) // returns 1

Not

const calculator = mockt(Calculator)
when(calculator).sum(not(anyNumber()), any()).returns(10)

calculator.sum('5', 2) // returns 10
calculator.sum(5, 2) // returns undefined

And

const calculator = mockt(Calculator)
when(calculator).sum(and(neq(2), neq(3)), any()).returns(10)

calculator.sum(1, 2) // returns 10
calculator.sum(2, 2) // returns undefined
calculator.sum(3, 2) // returns undefined

Or

const calculator = mockt(Calculator)
when(calculator).sum(or(2, 3), any()).returns(10)

calculator.sum(2, 2) // returns 10
calculator.sum(3, 2) // returns 10
calculator.sum(1, 2) // returns undefined

Verification

Verify method called

const calculator = mockt(Calculator)

calculator.sum(1, 2)

verify(calculator).sum(1, 2) // passes
verify(calculator).sum(any(), 2) // passes
verify(calculator).sum(2, 2) // fails

Verify property read

const user = mockt(User)

const name = user.name

verify(user).getProperty('name') // passes
verify(user).getProperty('lastname') // fails

Verify property set

const user = mockt(User)

user.name = 'Alice'

verify(user).setProperty('name', 'Alice') // passes
verify(user).setProperty('name', any()) // passes
verify(user).setProperty('name', 'Bob') // fails

Verify method called at least n times

const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(3, 4)
calculator.sum(5, 6)

verifyAtLeast(2, calculator).sum(any(), any()) // passes
verifyAtLeast(3, calculator).sum(any(), any()) // passes
verifyAtLeast(4, calculator).sum(any(), any()) // fails

Verify method called at most n times

const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)
calculator.sum(1, 4)

verifyAtMost(4, calculator).sum(1, any()) // passes
verifyAtMost(3, calculator).sum(1, any()) // passes
verifyAtMost(2, calculator).sum(1, any()) // fails

Verify method called exactly n times

const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)
calculator.sum(1, 4)

verifyTimes(3, calculator).sum(1, any()) // passes
verifyTimes(2, calculator).sum(1, any()) // fails

Verify method never called

const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)
calculator.sum(1, 4)

verifyNever(calculator).sum(1, 1) // passes
verifyNever(calculator).sum(1, 2) // fails

Verify multiple method calls

const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)
calculator.sum(1, 4)

verifyMulti(calculator)
    .sum(1, 2)
    .sum(1, 4)
    .called() // passes

Verify multiple methods never called

const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)
calculator.sum(1, 4)

verifyMulti(calculator)
    .sum(2, 2)
    .sum(2, 4)
    .never() // passes

Verify multiple methods called in expected order

const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)
calculator.sum(1, 4)

verifyMulti(calculator)
    .sum(1, 2)
    .sum(1, 4)
    .calledInOrder() // passes
const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)
calculator.sum(1, 4)

verifyMulti(calculator)
    .sum(1, 4)
    .sum(1, 2)
    .calledInOrder() // fails

Verify sequence of calls from different mocks or spies

import { verifySequence } from './verifySequence'

const billingService = mockt<BillingService>()
const deliveryService = mockt<DeliveryService>()

billingService.createFor(customer, products)
deliveryService.deliveryFor(customer.address, products)

verifySequence()
    .call(billingService).createFor(any(), any())
    .call(deliveryService).deliveryFor(any(), any()) // passes

Capture arguments

Last call

const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)

const [first, second] = capture(calculator).sum // returns [1, 3]
const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)

const [first, second] = captureLast(calculator).sum // returns [1, 3]

First call

const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)

const [first, second] = captureFirst(calculator).sum // returns [1, 2]

All calls

const calculator = mockt(Calculator)

calculator.sum(1, 2)
calculator.sum(1, 3)

const args = captureAll(calculator).sum // returns [[1, 2], [1, 3]]

Setters

const user = mockt(User)

user.name = 'Alice'

const [name] = capture(user).setProperty('name') // returns 'Alice'

Spies

const calculator = new Calculator()
const calculatorSpy = spy(calculator)

calculator.sum(1, 2) // returns 3

verify(calculatorSpy).sum(1, 2) // passes
verify(calculatorSpy).sum(2, 2) // fails

Reset

Calls

const calculator = mockt(Calculator)
calculator.sum(1, 2) // returns undefined
verify(calculatorSpy).sum(1, 2) // passes

resetCalls(calculator)

verify(calculatorSpy).sum(1, 2) // fails

All

const calculator = mockt(Calculator)
calculator.sum(1, 2) // returns undefined
verify(calculatorSpy).sum(1, 2) // passes

reset(calculator)

verify(calculatorSpy).sum(1, 2) // fails
const calculator = mockt(Calculator)
when(calculator).sum(2, any()).returns(3)
reset(calculator)

calculator.sum(1, 2) // returns undefined

Credits

Thanks to all the contributors of ts-mockito and Mockk.