package testx import ( "context" "testing" jobs_args "quyun/v2/app/jobs/args" "quyun/v2/database" "quyun/v2/providers/job" "quyun/v2/providers/jwt" "quyun/v2/providers/postgres" "github.com/riverqueue/river" "go.ipao.vip/atom" "go.ipao.vip/atom/container" "go.ipao.vip/atom/contracts" "go.ipao.vip/atom/opt" "go.uber.org/dig" "github.com/rogeecn/fabfile" . "github.com/smartystreets/goconvey/convey" ) func Default(providers ...container.ProviderContainer) container.Providers { return append(container.Providers{ postgres.DefaultProvider(), jwt.DefaultProvider(), job.DefaultProvider(), testJobWorkersProvider(), database.DefaultProvider(), }, providers...) } type orderRefundTestWorker struct { river.WorkerDefaults[jobs_args.OrderRefundJob] } func (w *orderRefundTestWorker) Work(ctx context.Context, job *river.Job[jobs_args.OrderRefundJob]) error { return nil } func testJobWorkersProvider() container.ProviderContainer { return container.ProviderContainer{ Provider: func(opts ...opt.Option) error { return container.Container.Provide(func(__job *job.Job) (contracts.Initial, error) { obj := &orderRefundTestWorker{} if err := river.AddWorkerSafely(__job.Workers, obj); err != nil { return nil, err } return obj, nil }, atom.GroupInitial) }, } } func Serve(providers container.Providers, t *testing.T, invoke any) { Convey("tests boot up", t, func() { // 关键语义:测试用例可能会在同一进程内多次调用 Serve。 // atom/config.Load 会向全局 dig 容器重复 Provide *viper.Viper,若不重置会导致 “already provided”。 // 因此每次测试启动前都重置容器,保证各测试套件相互独立。 container.Close() container.Container = dig.New() So(container.Container.Provide(func() context.Context { return context.Background() }), ShouldBeNil) file := fabfile.MustFind("config.toml") // localEnv := os.Getenv("ENV_LOCAL") // if localEnv != "" { // file = fabfile.MustFind("config." + localEnv + ".toml") // } So(atom.LoadProviders(file, providers), ShouldBeNil) So(container.Container.Invoke(invoke), ShouldBeNil) }) }