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

memorized-moebius

v1.1.0

Published

A never-panic deep dark object mainly intended for mocking.

Downloads

15

Readme

memorized-moebius

具有记忆力、永不异常的黑洞对象,主要用于单元测试 mock。

本地试用:npx memorized-moebius

背景

单元测试中,一个模块往往存在很多依赖,这些依赖需要被 mock,这给我们带来很多额外的复杂度。为了解决这个问题,我们一般会用 Proxy 构造一个「万能对象」,作为一个简易的 mock,我们称之为 Moebius(莫比乌斯)对象。

memorized-moebius 是一个易于使用的库,主要用于将这一类操作标准化。

用法

默认 moebius builder

默认的 moebius builder 可以构造一个默认 moebius 对象。

除了通用行为,默认的 moebius 对象实现了 toStringvalueOf,且 thencallsundefined;另外,如果在 jest 环境下,它还会被 jest.fn() 封装起来。

import buildDefaultMoebius from 'memorized-moebius';

const m = buildDefaultMoebius();

console.log(m.foo.toString()); // '[whatever Moebius]'
console.log(m.foo.bar().baz.valueOf()); // 42

// `then` 被设为 undefined,以防被识别为鸭子类型的 Promise 对象。
console.log(typeof m.then); // 'undefined'

// `calls` 被设为 undefined,以防被识别为鸭子类型的 jest.spy 函数。
console.log(typeof m.calls); // 'undefined'

通用行为

所有被 moebius builder 构造的 moebius 对象都会继承下列行为:

  • 如果被当作函数调用,会返回同一 builder 构造的、新的 moebius 对象;
  • 如果被取属性,若之前存/取过该属性,则返回之前存/取过的值,否则返回同一 builder 构造的、新的 moebius 对象;
  • 如果被设置属性,则该属性会被存下来,后续可以取到。

这一设计保证了 moebius 对象内部的一致性,从而尽可能模仿被 mock 到的真实对象,好像这些被用到的属性都真实存在一样。

builder 的 pipeline

每一个 moebius builder 都包含有一个 pipeline 数组,数组中包含了创建 moebius 对象的所有步骤:首先构造一个能返回新 moebius 对象的函数,然后把这个函数传入一些预处理器,然后将返回的值封装成 Proxy,最后再传入一些后置处理器。这一流水线适用于这个 builder 创建的所有 moebius 对象。

使用数组的 unshiftpush 操作,可以在 builder.pipeline 中添加预处理器和后置处理器。编写预处理器和后置处理器时,别忘了返回处理完成的对象。

// `buildDefaultMoebius` 其实是 `defaultBuilder.build` 的别名
import { defaultBuilder } from 'memorized-moebius';

// `unshift` 可以在 `new Proxy()` 操作之前添加一些预处理,以改变这个对象的基本行为
defaultBuilder.pipeline.unshift((object) => ({}));

// `push` 可以在 `new Proxy()` 操作之后添加一些后置处理,通常用于提前存入一些属性
defaultBuilder.pipeline.push((object) => {
  object.theAnswer = 42;
  return object;
});

// 上面两个操作将会应用于这个 builder 所 build 出来的所有对象
const m = defaultBuilder.build();
console.log(typeof m.foo.bar); // 'object'
console.log(m.what.is.theAnswer); // 42

创建全新的 builder

如果不需要默认 builder 的行为,除了直接修改 defaultBuilder.pipeline,还可以使用导出的 createMoebiusBuilder 函数。

需要注意的是,一个全新创建的 builder 会缺少 toStringvalueOf 等基础操作,最好先对它们进行定制,然后再使用。

import { createMoebiusBuilder } from 'memorized-moebius';
const builder = createMoebiusBuilder();

// 在这里对 `builder.pipeline` 进行定制

const m = builder.build();