一键导入
create-unit-test
Write or refactor unit tests following the canonical project pattern. Use when adding new unit tests or standardizing existing ones.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Write or refactor unit tests following the canonical project pattern. Use when adding new unit tests or standardizing existing ones.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Generate a Kotlin SingleModelValidationRule implementation for ONE rule from BPMN_STYLE_GUIDE.md. Use when drafting / iterating on a single rule, or when the user asks to 'generate a rule for <slug>', 'create the element-id-format rule', or 'add just this one rule to the test module'. For all rules at once, use generate-rules-to-enforce-bpmn-styleguide.
Generate Kotlin SingleModelValidationRule implementations for every deterministic (or hybrid) rule in BPMN_STYLE_GUIDE.md, so they can be enforced at test time by the bpmn-to-code-testing module. llm-only rules stay in the style guide for /validate-bpmn-style. Use when the user asks to 'generate validation rules from the style guide', 'enforce BPMN conventions in CI', or 'automate style checks in tests'. For a single rule, use generate-rule-to-enforce-bpmn-styleguide.
Interactively author a BPMN_STYLE_GUIDE.md for your project — a handbook that explains how the team models BPMN processes (naming, allowed elements, IDs, topics, engine-specific special cases). The output is a document humans can read; embedded YAML annotations let downstream skills enforce the rules. Use when the user asks to 'create a BPMN style guide', 'set up BPMN conventions', or 'define BPMN naming rules'.
Create a complete Spring Boot service project from a BPMN file with hexagonal architecture. Bootstraps via Spring Initializr, configures bpmn-to-code, and generates workers, use cases, and services wired to ProcessApi constants — no raw strings anywhere. Use when the user wants to start a new process service from a BPMN model.
Migrate generated API usage from bpmn-to-code v1.1.0 to v2.0.0. Use when the user asks to 'upgrade to v2', 'migrate from v1 to v2', 'fix TaskTypes references', or 'update bpmn-to-code API calls after upgrade'.
Replace hardcoded BPMN strings with references to the generated Process API. Use when the user asks to 'migrate to the process API', 'replace hardcoded strings with API references', 'use the generated BPMN API', or 'refactor to type-safe BPMN constants'.
| name | create-unit-test |
| description | Write or refactor unit tests following the canonical project pattern. Use when adding new unit tests or standardizing existing ones. |
| risk | safe |
Write and refactor unit tests following the canonical pattern used in this project.
class FooServiceTest {
// Mocks declared as private val at the top
private val somePort = mockk<SomePort>(relaxed = true)
// Subject under test is always named `underTest`
private val underTest = FooService(somePort = somePort)
@Test
fun `does something when condition is met`() {
// given: set up inputs and mock behaviour (omit section if single-line)
val input = SomeInput(
id = "order-42",
value = "test",
)
every { somePort.fetch(any()) } returns SomeResult(ok = true)
// when: the action is taken
val actual = underTest.doSomething(input)
// then: verify the result and all interactions
assertThat(actual).isEqualTo(SomeResult(ok = true))
verify { somePort.fetch(input) }
confirmVerified(somePort)
}
}
private val underTest — always this name for the subject under testprivate val <dep> = mockk<T>(relaxed = true) — one line per mock, declared before underTestprivate val fields at the bottom of the classprivate fun at the bottom of the class// given: / // when: / // then: comments when a section spans more than one linemockk<T>(relaxed = true) — never strict mocks unless you have a specific reasonevery { ... } returns ... for stubbingverify { ... } to assert interactionsconfirmVerified(dep1, dep2, ...) at the end to catch unexpected callsassertThat(actual).isEqualTo(expected) — never bare assert() or assertEquals()testBpmnModel(), testBpmnModelApi(), node()), use itAskUserQuestion to decide whether to create a builderfun foo(): Bar { return ... }fun foo(): Bar = .../** \n * description\n *//** description */Tests in bpmn-to-code-testing that exercise validation rules through the BpmnValidator fluent
builder are integration-style tests, not mock-based unit tests. The underTest / mockk /
confirmVerified pattern above does not apply to them. Use these conventions instead:
.result().violations for standard checks. Use
assertNoViolations() / assertNoViolations(ruleId) / assertHasViolations() for absence/presence,
and assertViolation(ruleId, elementId?, messageContains?) / assertViolationCount(n) for positive
checks. .result() is an escape hatch reserved for assertions the fluent API genuinely cannot express.private class declared below the tests, with members ordered
id → severity → phase → validate. Never an anonymous object : Rule val.TestRules — a rule used by more than one suite is defined once there and
exposed via a factory (TestRules.callActivityTargetExists()) plus an id constant
(TestRules.CALL_ACTIVITY_TARGET_EXISTS). One-off, behaviour-specific rules stay local to their class.// given: / // when: section, and no leading blank line after @Test..id constant (e.g. BpmnRules.TIMER_CRON_SYNTAX.id) over a magic string.@Test
fun `flags a call activity whose called process is absent`() {
BpmnValidator
.fromClasspath("bpmn/order-fulfillment/order-fulfillment.bpmn")
.engine(ProcessEngine.CAMUNDA_7)
.withRules(TestRules.callActivityTargetExists())
.validate()
.assertViolation(
ruleId = TestRules.CALL_ACTIVITY_TARGET_EXISTS,
elementId = "CallActivity_ProcessPayment",
messageContains = "paymentProcessing",
)
}
Testprivate val underTest is present and named correctlymockk<T>(relaxed = true)// given: / // when: / // then: comments present where sections are multi-lineassert())confirmVerified(...) called after all verify blocks when mocks are used