I've written this code for education purposes, now I need to write some test for it. First, I need to test method Worker, but I don't understand how can I do it properly? I'm totally new to test and to Go generally.
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)
}
}
}
I write some lines of testing code and I suppossed to check if Worker return nil when ctx.Done() is passed to channel Now this test doesn't work, it's stuck maybe because of infinite cycle in worker method. Then I need to check if method takes messages from queue and pass it to Download method.
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
}
CodePudding user response:
Go comes with a pretty extensive built-in testing library. See https://pkg.go.dev/testing
I would recommend looking at the below tutorials: