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

jasmine-mock-factory

v3.0.0

Published

A Jasmine helper for creating mocked classes

Downloads

1,661

Readme

Jasmine Mock Factory

Build Status Coverage Status

A Jasmine test util that uses a TypeScript class or an instance of a class to create a mock instance of that class.

Quick Start

import { SomeClass } from 'some-library';
import { MockFactory} from 'jasmine-mock-factory';

it('should pass', () => {
    const mockInstance = MockFactory.create(SomeClass);

    /* arrange */
    mockInstance._spy.doSomething._func.and.returnValue('awesome!');

    /* act */
    mockInstance.doSomething();  // returns 'awesome!'

    /* assert */
    expect(mockInstance.doSomething).toHaveBeenCalled();
}

Quick reference

  /* create a mock from a class*/
  const mockInstance1 = MockFactory.create(RealClass);

  /* create a mock from an instance*/
  const mockInstance2 = MockFactory.create(realInstance);

  /* access a function spy */
  const spy1 = mockInstance._spy.functionName._func

  /* access a getter spy */
  const spy2 = mockInstance._spy.propertyName._get

  /* access a setter spy */
  const spy3 = mockInstance._spy.propertyName._set

Prerequisite

  • This util is built with and for Jasmine test framework. Basic understanding of Jasmine is assumed.
  • This util requires ES6 Proxy.

Usage

Install

npm install jasmine-mock-factory --save-dev

Import

Import the library with ES6 Module Syntax:

import { MockFactory } from 'jasmine-mock-factory'

Creating a mock

From a TypeScript class

class RealClass {
  // This is a typescript class
}

...

const mockInstance = MockFactory.create(RealClass);

From an instance of a class

const realInstance: RealInterface = new RealClass();

...

const mockInstance = MockFactory.create(realInstance);

From window objects

/* make sure you have included dom types from the TypeScript library */
const mockWindow  = MockFactory.create(window);
const mockDocument = MockFactory.create(document);
const mockLocation = MockFactory.create(location);

Using a mock

  • MockFactory.create() will return an object with the same interface as the real object. You can invoke functions and access properties on this object.
  • In addition, the mock object provides a _spy facade, where you can access and config spies on functions and properties.
  const mockInstance = MockFactory.create(location);
  mockInstance.reload(); // use it as if it were the real window.location
  let temp = mockInstance.search; // use it as if it were the real window.search
  mockInstance.hash = 'myHash'; // use it as if it were the real window.hash
  mockInstance._spy.reload._func; // returns the spy behind location.reload
  mockInstance._spy.search._get; // returns the spy behind the getter for location.search
  mockInstance._spy.hash._set; // returns the spy behind the setter for location.hash

Invoking functions

  • All functions will have a jasmine.Spy as the initial value. The spy cannot be overwritten and returns undefined by default.
  • To access protected and private functions, cast the mockInstance as any or use bracket notation.
  mockInstance.publicFunction(42); // the spy behind it is invoked with 42

  (mockInstance as any).privateFunction(42);
  mockInstance['privateFunction'](42); // equivalent

Spying/stubbing functions

  • You can change return values of functions or assert their calls by accessing them directly or through the _spy facade.
  • Access a function spy on mockInstance._spy.functionName._func.
  /* stubbing a public function */
  mockInstance._spy.publicFunction._func.and.returnValue(42);
  (mockInstance.publicFunction as jasmine.Spy).and.returnValue(42); // equivalent, but not recommented because it requires casting

  /* stubbing a private function */
  mockInstance._spy.privateFunction._func.and.returnValue(42);
  ((mockInstance as any).privateFunction as jasmine.Spy).and.returnValue(42); // equivalent, but not recommented because it requires casting twice

Accessing properties

  • All properties have undefined as the initial value. The value can be overwritten with anything.
  • You have read and write access to any property, even if they were readonly in the real object.
  • To read or write a protected or private property, cast the mockInstance as any or use bracket notation.
  • To write a readonly property, cast the mockInstance as any. The bracket notation won't work.
  • By default, modification to the properties will persist, even if a getter or setter exists in the real object.
  /* persist modification */
  mockInstance.publicProperty = 42;
  let temp = mockInstance.publicProperty; // temp = 42;

  /* access readonly property */
  mockInstance.readonlyProperty = 42; // typescript compiler error
  (mockInstance as any).readonlyProperty = 42; // no problem
  mockInstance['readonlyProperty'] = 42; // typescript compiler error

  /* access private property */
  (mockInstance as any).privateProperty = 'foo';
  mockInstance['privateProperty'] = 'foo'; // equivalent

Spying/stubbing getters and setters

  • All properties have spies on the getter and setter, even if the getter and setter don't exist in the real object.
  • Access a getter spy on mockInstance._spy.propertyName._get.
  • Access a setter spy on mockInstance._spy.propertyName._set.
  • NOTE: modification to the properties will not persist after getter or setter spies are customized
  • NOTE: expect(mockInstance.someProperty).toBe(...) will trigger mockInstance._spy.someProperty._get. Design the sequence of your assertions carefully to avoid shooting yourself in the foot.
  /* assert getter calls */
  let temp = mockInstance.publicProperty;
  expect(mockInstance._spy.publicProperty._get).toHaveBeenCalled();

  /* assert setter calls on a public property */
  mockInstance.publicProperty = 42;
  expect(mockInstance._spy.publicProperty._set).toHaveBeenCalledWith(42);

  /* customize setter */
  expect(mockInstance.publicProperty).toBe(42); // pass. setter hasn't been customized
  mockInstance._spy.publicProperty._set.and.callFake(() => { /* noop */});
  mockInstance.publicProperty = 100;
  expect(mockInstance.publicProperty).toBe(100); // fail. expect 42 to be 100. setter was customized

  /* assert setter calls on a private property */
  mockInstance['privateProperty'] = 42;
  expect(mockInstance._spy.privateProperty._set).toHaveBeenCalledWith(42);

  /* customize getter */
  expect(mockInstance['privateProperty']).toBe(42); // pass. getter hasn't been customized
  mockInstance._spy.privateProperty._get.and.returnValue(100);
  mockInstance['privateProperty'] = 42;
  expect(mockInstance['privateProperty']).toBe(42); // fail, expect 100 to be 42. getter was customzied

Develope

  • npm install to install dev dependencies
  • npm run build to build the library
  • npm run test to test the library