我为教育目的编写了这段代码,现在我需要为它编写一些测试. 首先,我需要测试方法工作者,但我不明白如何才能正确地进行测试? 我对测试和大体来说都是全新的.
package worker
import (
"context"
"fmt"
)
type Queue interface {
TakeMessage() (<-chan string, error)
}
type Download interface {
Download(url string) error
}
type Worker struct {
queue Queue
download Download
}
func NewWorker(queue Queue, download Download) *Worker {
newWorker := Worker{}
newWorker.queue = queue
newWorker.download = download
return &newWorker
}
func (w *Worker) Worker(ctx context.Context) error {
msgs, err := w.queue.TakeMessage()
if err != nil {
return fmt.Errorf("error while consume queue: %w", err)
}
for {
select {
case <-ctx.Done():
return nil
case msg := <-msgs:
fmt.Println(msg)
w.download.Download(msg)
}
}
}
我编写了几行测试代码,并假设在将ctx.Done()传递给通道时判断Worker是否返回nil.现在这个测试不起作用,可能是因为Worker方法中的无限循环而停滞.然后,我需要判断方法是否从队列中获取消息并将其传递给Download方法.
package worker
import (
"context"
"errors"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
type MockQueue struct {
mock.Mock
}
type MockDownloader struct {
mock.Mock
}
func (m *MockQueue) TakeMessage() (<-chan string, error) {
strCh := make(chan string)
strCh <- "some_url/some.txt"
return strCh, nil
}
func (d *MockDownloader) Download(url string) error {
if url == "some_url/some.txt" {
return nil
} else {
return errors.New(url)
}
}
func TestWorkerCloseContext(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
resultCh := make(chan error)
newQueue := &MockQueue{}
newDownload := &MockDownloader{}
newWorker := Worker{newQueue, newDownload}
go func() {
resultCh <- newWorker.Worker(ctx)
}()
cancel()
assert.Nil(t, <-resultCh)
}
func TestWorkerMessageReceive(t \*testing.T) {
ctx, cancel := context.WithCancel(context.Background())
resultCh := make(chan error)
newQueue := &MockQueue{}
newDownload := &MockDownloader{}
newWorker := Worker{newQueue, newDownload}
go func() {
resultCh \<- newWorker.Worker(ctx)
}()
//some code here
}