在我的情况下,我应该如何正确地测试方法?

huangapple go评论110阅读模式
英文:

How can I test method in proper way in my case?

问题

我已经为教育目的编写了这段代码,现在我需要为它编写一些测试。首先,我需要测试Worker方法,但我不明白如何正确地进行测试。我对测试和Go语言都完全不熟悉。

我写了一些测试代码,我想检查当将ctx.Done()传递给通道时,Worker方法是否返回nil。现在这个测试不起作用,可能是因为worker方法中有一个无限循环。然后,我需要检查方法是否从队列中获取消息并将其传递给Download方法。

  1. package worker
  2. import (
  3. "context"
  4. "errors"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/mock"
  8. )
  9. type MockQueue struct {
  10. mock.Mock
  11. }
  12. type MockDownloader struct {
  13. mock.Mock
  14. }
  15. func (m *MockQueue) TakeMessage() (<-chan string, error) {
  16. strCh := make(chan string)
  17. strCh <- "some_url/some.txt"
  18. return strCh, nil
  19. }
  20. func (d *MockDownloader) Download(url string) error {
  21. if url == "some_url/some.txt" {
  22. return nil
  23. } else {
  24. return errors.New(url)
  25. }
  26. }
  27. func TestWorkerCloseContext(t *testing.T) {
  28. ctx, cancel := context.WithCancel(context.Background())
  29. resultCh := make(chan error)
  30. newQueue := &MockQueue{}
  31. newDownload := &MockDownloader{}
  32. newWorker := Worker{newQueue, newDownload}
  33. go func() {
  34. resultCh <- newWorker.Worker(ctx)
  35. }()
  36. cancel()
  37. assert.Nil(t, <-resultCh)
  38. }
  39. func TestWorkerMessageReceive(t *testing.T) {
  40. ctx, cancel := context.WithCancel(context.Background())
  41. resultCh := make(chan error)
  42. newQueue := &MockQueue{}
  43. newDownload := &MockDownloader{}
  44. newWorker := Worker{newQueue, newDownload}
  45. go func() {
  46. resultCh <- newWorker.Worker(ctx)
  47. }()
  48. // 这里是一些代码
  49. }

希望这可以帮助你进行测试。如果你有任何其他问题,请随时问我。

英文:

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.

  1. package worker
  2. import (
  3. &quot;context&quot;
  4. &quot;fmt&quot;
  5. )
  6. type Queue interface {
  7. TakeMessage() (&lt;-chan string, error)
  8. }
  9. type Download interface {
  10. Download(url string) error
  11. }
  12. type Worker struct {
  13. queue Queue
  14. download Download
  15. }
  16. func NewWorker(queue Queue, download Download) *Worker {
  17. newWorker := Worker{}
  18. newWorker.queue = queue
  19. newWorker.download = download
  20. return &amp;newWorker
  21. }
  22. func (w *Worker) Worker(ctx context.Context) error {
  23. msgs, err := w.queue.TakeMessage()
  24. if err != nil {
  25. return fmt.Errorf(&quot;error while consume queue: %w&quot;, err)
  26. }
  27. for {
  28. select {
  29. case &lt;-ctx.Done():
  30. return nil
  31. case msg := &lt;-msgs:
  32. fmt.Println(msg)
  33. w.download.Download(msg)
  34. }
  35. }
  36. }

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.

  1. package worker
  2. import (
  3. &quot;context&quot;
  4. &quot;errors&quot;
  5. &quot;testing&quot;
  6. &quot;github.com/stretchr/testify/assert&quot;
  7. &quot;github.com/stretchr/testify/mock&quot;
  8. )
  9. type MockQueue struct {
  10. mock.Mock
  11. }
  12. type MockDownloader struct {
  13. mock.Mock
  14. }
  15. func (m *MockQueue) TakeMessage() (&lt;-chan string, error) {
  16. strCh := make(chan string)
  17. strCh &lt;- &quot;some_url/some.txt&quot;
  18. return strCh, nil
  19. }
  20. func (d *MockDownloader) Download(url string) error {
  21. if url == &quot;some_url/some.txt&quot; {
  22. return nil
  23. } else {
  24. return errors.New(url)
  25. }
  26. }
  27. func TestWorkerCloseContext(t *testing.T) {
  28. ctx, cancel := context.WithCancel(context.Background())
  29. resultCh := make(chan error)
  30. newQueue := &amp;MockQueue{}
  31. newDownload := &amp;MockDownloader{}
  32. newWorker := Worker{newQueue, newDownload}
  33. go func() {
  34. resultCh &lt;- newWorker.Worker(ctx)
  35. }()
  36. cancel()
  37. assert.Nil(t, &lt;-resultCh)
  38. }
  39. func TestWorkerMessageReceive(t \*testing.T) {
  40. ctx, cancel := context.WithCancel(context.Background())
  41. resultCh := make(chan error)
  42. newQueue := &amp;MockQueue{}
  43. newDownload := &amp;MockDownloader{}
  44. newWorker := Worker{newQueue, newDownload}
  45. go func() {
  46. resultCh \&lt;- newWorker.Worker(ctx)
  47. }()
  48. //some code here
  49. }

答案1

得分: 2

Go语言自带了一个相当丰富的内置测试库。请参考https://pkg.go.dev/testing。

我建议你看一下以下教程:

英文:

Go comes with a pretty extensive built-in testing library. See https://pkg.go.dev/testing

I would recommend looking at the below tutorials:

huangapple
  • 本文由 发表于 2022年9月9日 21:20:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/73662830.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定