Token导航 LogoToken导航TokenDH.com
开发需要联网github未标认证来源可访问许可证需确认审计通过

nullables-test可空测试

Agent Skill

用于辅助测试设计、自动化测试、用例整理和回归验证。它适合让 Agent 编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需要确认项目测试框架、运行命令和夹具数据,避免为了通过测试而改坏真实逻辑;涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。

总安装

303

周安装

13

GitHub Stars

公开资料未说明

下载量

106
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:nullables-test(可空测试)
来源仓库:https://github.com/danielbush/skills
仓库路径:skills/nullables-test
安装命令:
npx skills add https://github.com/danielbush/skills --skill nullables-test
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/danielbush/skills --skill nullables-test

简介

nullables-test 用于辅助测试设计、自动化测试和回归验证。

  • 适合让 Agent 编写单元测试、端到端测试或根据日志定位问题。
  • 使用时需确认项目测试框架、运行命令和夹具数据,避免误改逻辑。
  • 涉及浏览器或外部服务时,应区分本地模拟与生产环境。
  • 可结合来源仓库进一步核验功能细节和使用限制。

SKILL.md

Nullables Test

Write tests for code that follows the Nullables pattern. Tests should illustrate how the system works — grounding the codebase's own concepts through concrete examples.

Vocabulary

This skill uses terms from references/vocabulary.md. Key terms: HARDWIRED_INFRA, INJECTED_INFRA, DUAL_FACTORY, NULLABLE, CONFIGURABLE_RESPONSE, OUTPUT_TRACKING, INFRASTRUCTURE_WRAPPER, NULLABLE_CLASS, CREATE_BOUNDARY_RULE, VALUE_OBJECT.

Philosophy

Tests are not just for coverage — they are illustrations of the system. A developer reading the tests should learn:

  • What the class does and why it exists
  • What its key behaviors are, expressed in the system's own vocabulary
  • What OUTSIDE_WORLD interactions it has (visible through CONFIGURABLE_RESPONSE and OUTPUT_TRACKING)
  • How it handles important edge cases

Write the minimum number of tests that ground these concepts. Don't exhaustively test every path — focus on tests that teach a reader about the system. The system being tested has its own domain, its own vocabulary, its own architecture. The tests should reflect that.

Build confidence from the top down. Because nullables give us sociable, narrow, state-based unit tests, we can test exhaustively at higher, more meaningful levels — exercising real behavior through real dependency graphs without mocks or slow I/O. Start at the middle or top of the dependency graph where tests illustrate the most about how the system works. Lower-level tests are fine when they add clarity or catch things the higher-level tests don't reach — drop down as needed, guided by coverage and judgement. The goal is pragmatic confidence, not layer-by-layer exhaustiveness.

Precondition: Is This Class Ready To Test?

Before writing tests, verify the class under test is testable. Walk this checklist:

1. No HARDWIRED_INFRA remaining

Scan the class for any OUTSIDE_WORLD calls used directly (imported and called inline). If found, the class is not ready — the nullables-refactor skill should be applied first.

2. Class has DUAL_FACTORY

The class must have .create() and .createNull(). If not, it's not ready.

3. All INJECTED_INFRA has .createNull()

For each dependency injected through the constructor:

  • Does it have .createNull()?
  • Does .createNull() accept CONFIGURABLE_RESPONSE parameters?
  • If not → that dependency needs to be made nullable first.

This may require recursive refactoring: follow the dependency graph down to the leaves (INFRASTRUCTURE_WRAPPERs). Every node in the chain must have .createNull() for the top-level .createNull() to produce a fully nulled instance.

The chain:

ClassUnderTest.createNull()
  → calls DependencyA.createNull()
    → calls InfraWrapperX.createNull()  ← leaf, has EMBEDDED_STUB
  → calls DependencyB.createNull()
    → calls InfraWrapperY.createNull()  ← leaf, has EMBEDDED_STUB

If any link in this chain is missing .createNull(), flag it. Tell the human which dependency needs work and suggest using nullables-refactor on it.

4. .createNull() actually nulls everything

Create an instance via .createNull() with no arguments. It should:

  • Execute without errors
  • Not make any real OUTSIDE_WORLD calls
  • Return sensible defaults

If .createNull() throws or makes real I/O calls, the EMBEDDED_STUBs or CONFIGURABLE_RESPONSE defaults are incomplete.

Writing Tests

How to instantiate in tests

There are two distinct cases — getting this right matters:

Testing Foo itself (Foo is the class under test)

Use new Foo(...) directly and pass in nulled dependencies with specific CONFIGURABLE_RESPONSE values:

// Testing Foo — use `new` so you control each dependency's configuration
const bar = Bar.createNull({ response: specificValue });
const client = HttpClient.createNull({ status: 404 });
const foo = new Foo(bar, client);

This gives you fine-grained control over each dependency. You can configure exactly the scenario you want to test. Foo.createNull() would bundle its own defaults, which may not expose the granularity you need.

Foo as a dependency (testing something that uses Foo)

Use Foo.createNull() — its bundled defaults keep the test focused on the actual class under test:

// Testing AppService which depends on Foo
// We don't care about Foo's internals here
const appService = new AppService(Foo.createNull());

Foo.createNull() exists to make Foo a convenient, safe dependency in other tests. It provides sensible defaults so the test reader doesn't get distracted by Foo's configuration.

What to test

For each class, write tests that illustrate its key behaviors:

For INFRASTRUCTURE_WRAPPERs (leaf nodes)

  • Test .createNull() works: creating a NULLABLE instance should succeed with defaults
  • Test CONFIGURABLE_RESPONSE: configure a specific response and verify the wrapper returns it
  • Test OUTPUT_TRACKING: if the wrapper has trackX(), verify it records interactions
  • Test error paths: configure error responses via CONFIGURABLE_RESPONSE to verify error handling

These tests verify the wrapper's contract — that the EMBEDDED_STUB faithfully represents what the real system does at the behavior level.

For NULLABLE_CLASSes (orchestrators)

  • Test the core behavior: what does this class *do*? Instantiate with new and pass nulled deps, call its methods, verify the result. The test should read like a description of the class's purpose.
  • Test with CONFIGURABLE_RESPONSE: configure specific dependency responses to test how the class handles different inputs from the outside world
  • Test OUTPUT_TRACKING on dependencies: verify the class makes the right calls to its dependencies (what was written, in what order) — use trackers, not mocks
  • Test edge cases that matter to the domain: not every edge case, just the ones that illuminate how the system handles its key scenarios

For VALUE_OBJECTs

  • Test .create() and .createTestInstance()
  • Test any transformation methods
  • Keep it simple — these are usually straightforward

For PURE code

  • Test with plain inputs and outputs
  • No nullable machinery needed

Example

describe('ReportGenerator', () => {
  // ReportGenerator is the class under test — use `new` with nulled deps
  // so we can configure each dependency's responses for the test scenario

  it('generates a report from a template and data', () => {
    const fileStore = FileStore.createNull({
      templates: { 'Sales.html': '<h1>{{title}}</h1>{{rows}}' },
    });
    const webhook = WebhookClient.createNull();
    const generator = new ReportGenerator(fileStore, webhook);

    const result = generator.generate({
      title: 'Sales',
      rows: [{ label: 'Q1', value: 100 }],
    });

    expect(result).toContain('<h1>Sales</h1>');
  });

  it('notifies the webhook after writing the report', () => {
    const fileStore = FileStore.createNull();
    const webhook = WebhookClient.createNull();
    const tracker = webhook.trackNotifications();
    const generator = new ReportGenerator(fileStore, webhook);

    generator.generate({ title: 'Sales', rows: [] });

    // State-based: what was sent, not how
    expect(tracker.data).toEqual([
      { title: 'Sales', path: './output/Sales-report.html' },
    ]);
  });
});

What NOT to do

  • Don't use mocks, spies, or stubs — use .createNull() with CONFIGURABLE_RESPONSE instead
  • Don't test implementation details — test behaviors and outcomes
  • Don't write exhaustive tests — write illustrative ones that teach a reader about the system
  • Don't use .create() in unit tests.create() is for narrow integration tests that verify real OUTSIDE_WORLD behavior, run separately
  • Don't add tests for things that can't fail — if the code is PURE and trivial, a test adds noise not signal
  • Don't use Foo.createNull() when testing Foo itself — use new Foo(deps.createNull(...)) for fine-grained control

Integration Tests (Sparingly)

For INFRASTRUCTURE_WRAPPERs only, write a small number of narrow integration tests using .create():

  • Verify the real wrapper talks to the real external system correctly
  • Verify the EMBEDDED_STUB's behavior matches reality
  • These go in a separate test directory/command (they're slow, need real services)
  • Keep them few — they exist to validate the contract, not to test business logic

Output

Present the tests with brief commentary explaining what each test illustrates about the system. Group tests by the class they're testing. If any precondition check fails, report what's blocking and what needs to happen first.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

35.85%
按下载量换算38

Claude

26.47%
按下载量换算28

Cursor

18.7%
按下载量换算20

Gemini CLI

8.99%
按下载量换算10

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills