在 Manus 中运行任何 Skill
一键导入
一键导入
一键在 Manus 中运行任何 Skill
开始使用crud-test
星标349
分支64
更新时间2026年3月25日 07:16
PowerX CRUD 测试规则(Service 必测、Repo 可选集测)。
安装
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
SKILL.md
readonly菜单
PowerX CRUD 测试规则(Service 必测、Repo 可选集测)。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
PowerX API 命名与访问规范(/api/v1、/admin、/internal 边界)。
PowerX 底座 Capability 治理与发布准入规则。用于审计 REST/OpenAPI/gRPC/Gin 生成的能力候选、正式 platform_capabilities 目录、Capability Registry 登记、agent_usable/permission_code/risk_level 元数据、ignore 清单和缺失能力;当用户要求“重新识别能力”“能力是否能发布”“补齐能力登记”“检查 capability-gen/audit/check”“底座接口暴露给插件/agent”时使用。
PowerX STS 与插件鉴权规范(Exchange、KeyRing、拦截器、审计)。
PowerX REST 契约规则(资源命名、分页、错误、版本化)。
PowerX CRUD 依赖注入规则(Deps 单入口、构造注入、跨传输复用)。
PowerX CRUD DTO 规则(输入输出分离、分页、校验)。
| name | crud-test |
| description | PowerX CRUD 测试规则(Service 必测、Repo 可选集测)。 |
本文件内嵌规则。
kind: ruleset
name: crud_test
version: 1.0.0
owner: powerx
status: stable
meta:
intent: >
要求 CRUD 关键层有最小可用测试覆盖:Service 单元测试必须存在;
可选提供 Repository 的集成测试(sqlite/pg 临时库)。
references:
- crud_service.yaml
- crud_repository.yaml
scope:
applies_to:
- "internal/service/**/**_service_test.go"
- "internal/repository/**/**_repo_test.go"
principles:
- Service 层单测为必选:mock Repo,覆盖 404/409/成功分支与事务失败。
- Repository 可选集测:使用临时 DB(prefer sqlite-in-memory 或 testcontainer PG)。
- 测试不依赖传输层(无 gin/grpc 依赖)。
checks:
# Service 单测存在
- id: service.tests.exist
level: error
when: { glob: "internal/service/**/**_service.go" }
assert:
- must_have_companion_test: true
# Service 测试基础要素
- id: service.tests.shape
level: warn
when: { glob: "internal/service/**/**_service_test.go" }
assert:
- must_import: ["testing"]
- should_import_any: ["github.com/stretchr/testify/assert","github.com/stretchr/testify/require"]
- must_not_import: ["github.com/gin-gonic/gin","google.golang.org/grpc"]
# Repository 集测(可选,存在则建议约束)
- id: repo.tests.optional
level: warn
when: { glob: "internal/repository/**/**_repo_test.go" }
assert:
- should_import_any: ["gorm.io/driver/sqlite","github.com/testcontainers/testcontainers-go"]
- should_contain_any: ["sqlite.Open(\"file::memory:?cache=shared\")","testcontainers"]
acceptance:
checklist:
- "[ ] 每个 Service 至少有一个 *_service_test.go 覆盖核心分支(404/409/成功/事务失败)"
- "[ ] 测试不依赖 HTTP/gRPC 传输"
- "[ ] 有基础断言库(testify)"
- "[ ] (可选)Repository 集测基于临时 DB"
templates:
service_test_go: |
// internal/service/{{domain}}/{{resource}}_service_test.go
package {{domain}}svc_test
import (
"context"
"errors"
"testing"
"{{module_path}}/internal/app/shared"
svc "{{module_path}}/internal/service/{{domain}}"
repo "{{module_path}}/internal/repository/{{domain}}"
"github.com/stretchr/testify/assert"
"gorm.io/gorm"
)
// 伪造 Repo(可替换为 gomock)
type fakeRepo struct {
create func(ctx context.Context, db *gorm.DB, tenantID uint64, in any) error
get func(ctx context.Context, db *gorm.DB, tenantID uint64, id string) (any, error)
}
// 满足接口(示例,按你实际接口补全)
// ...
func Test_Get_NotFound(t *testing.T) {
d := &shared.Deps{}
fr := &fakeRepo{
get: func(ctx context.Context, db *gorm.DB, tenantID uint64, id string) (any, error) {
return nil, gorm.ErrRecordNotFound
},
}
s := svc.New{{Entity}}Service(d, fr)
_, err := s.Get(context.Background(), 1, "id-x")
assert.Error(t, err)
assert.Equal(t, svc.ErrNotFound, err)
}
repo_sqlite_test_go: |
// internal/repository/{{domain}}/{{resource}}_repo_test.go
package {{domain}}repo_test
import (
"context"
"testing"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
repo "{{module_path}}/internal/repository/{{domain}}"
m "{{module_path}}/pkg/corex/db/persistence/model/{{domain}}"
"github.com/stretchr/testify/require"
)
func newDB(t *testing.T) *gorm.DB {
db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
require.NoError(t, err)
require.NoError(t, db.AutoMigrate(&m.{{Entity}}{}))
return db
}
func Test_Create_And_Get(t *testing.T) {
db := newDB(t)
r := repo.New{{Entity}}Repo(db)
ctx := context.Background()
in := &m.{{Entity}}{TenantID: 1, Name: "n"}
require.NoError(t, r.Create(ctx, db, 1, in))
got, err := r.GetByID(ctx, db, 1, in.ID)
require.NoError(t, err)
require.NotNil(t, got)
}