首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模拟第三方服务Go时出现错误:索引超出范围[-1]

模拟第三方服务Go时出现错误:索引超出范围[-1]
EN

Stack Overflow用户
提问于 2021-04-13 23:29:33
回答 1查看 42关注 0票数 0

所以我使用了一个名为Gocron的包。代码应用程序代码本身通过接口工作得很好,但是一旦我试图在测试中模拟出包,问题就来了。

下面是我的测试文件,以及我为Gocron包创建的mock:

代码语言:javascript
复制
type mockGoCron struct{}

func (mSh *mockGoCron) StartBlocking() {
    fmt.Println("hey")
}

func (mSh *mockGoCron) Every(interface{}) *gocron.Scheduler {
    return gocron.NewScheduler(time.UTC)
}

func (mSh *mockGoCron) Seconds() *gocron.Scheduler {
    return &gocron.Scheduler{}
}

func (mSh *mockGoCron) Minutes() *gocron.Scheduler {
    return &gocron.Scheduler{}
}

func NewMockGoCron() *mockGoCron {
    return &mockGoCron{}
}

var (
    sh scheduler.Scheduler = scheduler.Scheduler{
        Sched:   NewMockGoCron(),
        AllJobs: scheduler.AllJobs{},
    }
    job scheduler.Job = scheduler.Job{
        Name:              "testJob",
        TimeInterval:      "1",
        TimeUnit:          "seconds",
        ActionTriggerName: "testAction",
    }
)

var _ = Describe("Scheduler", func() {
    Describe("Initializing jobs", func() {
        Context("When initializing a job", func() {
            It("Should return true", func() {
                Expect(sh.InitJob(job)).To(Equal(true))
                sh.InitJob(job)
            })
        })
    })
})

以下是应用程序代码:

代码语言:javascript
复制
//main.go
func main() {
    ...
    sh := scheduler.NewScheduler()
    sh.InitScheduler()
}

// scheduler.go
type SchedulerInterface interface {
    StartBlocking()
    Every(interface{}) *gocron.Scheduler
    Seconds() *gocron.Scheduler
    Minutes() *gocron.Scheduler
}

type Scheduler struct {
    Sched   SchedulerInterface
    AllJobs AllJobs
}

type ScheduleHandler interface {
    InitScheduler(*gocron.Scheduler, AllJobs) bool
    InitJob(*gocron.Scheduler, Job) bool
}

func NewScheduler() *Scheduler {
    goC := gocron.NewScheduler(time.UTC)
    return &Scheduler{
        Sched:   goC,
        AllJobs: AllJobs{},
    }
}

func (sh *Scheduler) InitJob(job Job) bool {
    timeInterval, _ := strconv.Atoi(job.TimeInterval)

    switch job.TimeUnit {
    case "seconds":
        sh.Sched.Every(timeInterval).Seconds().Do(doSomeFunc)
        return true
    case "minutes":
        sh.Sched.Every(timeInterval).Minutes().Do(doSomeFunc)
        return true
    }

    return false
}

// Initialize Scheduler
func (sh *Scheduler) InitScheduler() {
    sh.AllJobs.ParseJobs("./jobs.json")

    for k, v := range sh.AllJobs.Jobs {
        sh.InitJob(v)
    }

    sh.Sched.StartBlocking()
}

下面是错误:

代码语言:javascript
复制
Test Panicked
      runtime error: index out of range [-1]
      /usr/local/go/src/runtime/panic.go:88

      Full Stack Trace
      github.com/go-co-op/gocron.(*Scheduler).getCurrentJob(...)
        /Users/garrettlove/go/pkg/mod/github.com/go-co-op/gocron@v1.1.0/scheduler.go:743
      github.com/go-co-op/gocron.(*Scheduler).setUnit(0xc000140240, 0x1)
        /Users/garrettlove/go/pkg/mod/github.com/go-co-op/gocron@v1.1.0/scheduler.go:604 +0x17a
      github.com/go-co-op/gocron.(*Scheduler).Seconds(...)
        /Users/garrettlove/go/pkg/mod/github.com/go-co-op/gocron@v1.1.0/scheduler.go:629
      bitbucket.org/garrettlove/dfd-api/internal/scheduler.(*Scheduler).InitJob(0x16a1ca0, 0x13c1508, 0x7, 0x13bd99e, 0x1, 0x13c13b8, 0x7, 0x13c363e, 0xa, 0x16c3e20)
        /Users/garrettlove/go/src/bitbucket.org/garrettlove8/dfd-api/rules-processor/internal/scheduler/scheduler.go:47 +0x165
      bitbucket.org/garrettlove/dfd-api/internal/scheduler_test.glob..func1.1.1.1()
        /Users/garrettlove/go/src/bitbucket.org/garrettlove8/dfd-api/rules-processor/internal/scheduler/scheduler_test.go:183 +0x65
      github.com/onsi/ginkgo/internal/leafnodes.(*runner).runSync(0xc0000268a0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/internal/leafnodes/runner.go:113 +0xa3
      github.com/onsi/ginkgo/internal/leafnodes.(*runner).run(0xc0000268a0, 0x104310a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/internal/leafnodes/runner.go:64 +0xd7
      github.com/onsi/ginkgo/internal/leafnodes.(*ItNode).Run(0xc00000eaa0, 0x1432340, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/internal/leafnodes/it_node.go:26 +0x67
      github.com/onsi/ginkgo/internal/spec.(*Spec).runSample(0xc0001d2000, 0x0, 0x1432340, 0xc000072b40)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/internal/spec/spec.go:215 +0x691
      github.com/onsi/ginkgo/internal/spec.(*Spec).Run(0xc0001d2000, 0x1432340, 0xc000072b40)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/internal/spec/spec.go:138 +0xf2
      github.com/onsi/ginkgo/internal/specrunner.(*SpecRunner).runSpec(0xc0001466e0, 0xc0001d2000, 0x0)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/internal/specrunner/spec_runner.go:200 +0x111
      github.com/onsi/ginkgo/internal/specrunner.(*SpecRunner).runSpecs(0xc0001466e0, 0x1)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/internal/specrunner/spec_runner.go:170 +0x127
      github.com/onsi/ginkgo/internal/specrunner.(*SpecRunner).Run(0xc0001466e0, 0xc000012d60)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/internal/specrunner/spec_runner.go:66 +0x117
      github.com/onsi/ginkgo/internal/suite.(*Suite).Run(0xc000127490, 0x1d7e210, 0xc000001b00, 0x13c5f9c, 0xf, 0xc000061340, 0x1, 0x1, 0x1439ac0, 0xc000072b40, ...)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/internal/suite/suite.go:79 +0x586
      github.com/onsi/ginkgo.runSpecsWithCustomReporters(0x1432820, 0xc000001b00, 0x13c5f9c, 0xf, 0xc00004a728, 0x1, 0x1, 0xc00004a738)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/ginkgo_dsl.go:238 +0x238
      github.com/onsi/ginkgo.RunSpecs(0x1432820, 0xc000001b00, 0x13c5f9c, 0xf, 0x6c49ac23d89c6)
        /Users/garrettlove/go/pkg/mod/github.com/onsi/ginkgo@v1.16.0/ginkgo_dsl.go:213 +0xa7
      bitbucket.org/garrettlove/dfd-api/internal/scheduler_test.TestJobs(0xc000001b00)
        /Users/garrettlove/go/src/bitbucket.org/garrettlove8/dfd-api/rules-processor/internal/scheduler/scheduler_suite_test.go:12 +0x98
      testing.tRunner(0xc000001b00, 0x13e16b8)
        /usr/local/go/src/testing/testing.go:1123 +0xef
      created by testing.(*T).Run
        /usr/local/go/src/testing/testing.go:1168 +0x2b3

这里我漏掉了什么?我在嘲笑什么东西是不正确的吗?任何帮助都是非常感谢的!

EN

回答 1

Stack Overflow用户

发布于 2021-04-15 20:35:27

Scheduler的Every() appends an internal jobs array

在您的模拟实现中,Every()只返回一个从未调用过Every的调度器。在随后对Seconds()的调用中,由于此内部数组从未填充任何元素,因此getCurrentJob会死机。

如果您为“抽象的”gocron提供了一个SchedulerInterface,那么它的方法返回*gocron.Scheduler就有点奇怪了。在某种意义上,它仍然会导致代码几乎不依赖于gocron。IMO有两个选项:

  1. 围绕gocron的调度程序创建了一个包装器:这允许对返回类型等进行更多的控制。另外,您的包装器可以实现一个自定义接口,您可以在测试中模拟该接口。
  2. (最小的工作量)仅使用gocron本身。测试完成后,您只需调用调度器的Stop()即可。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67077923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档