GoLang Testing

Table of Contents

Running tests

https://stackoverflow.com/questions/16353016/how-to-go-test-all-tests-in-my-project

go test will run the tests only in the directory in which it it run.

e.g. To run tests on morestrings package, we have to run go test in that directory.

How to `go test` all tests in my project?

This should run all tests in current directory and all of its subdirectories. So, we can run it from the root directory of the project.

go test ./...

This should run all tests for given specific directories:

go test ./tests/... ./unit-tests/... ./my-packages/...

This should run all tests with import path prefixed with foo/:

go test foo/...

This should run all tests import path prefixed with foo:

go test foo...

This should run all tests in your $GOPATH:

go test ...

Mocking functions

  1. https://stackoverflow.com/questions/19167970/mock-functions-in-go
  2. Other libraries out there
    1. xgo
    2. gomonkey
  3. My preference
    1. I found that using the var syntax for mocking functions is the most straight-forward
    2. It is just slightly more verbose but it is very easy to write, understand, and modify
    3. It makes maintenance so much easy
    4. I ran into errors like “double seq is less than call seq” when using gomonkey
    5. I did not use xgo all that much
    6. If you change your function definition to use a variable instead:
      var get_page = func(url string) string {
               ...
      }
      
      You can override it in your tests:
      func TestDownloader(t *testing.T) {
      
                // Backup original functions. We need to restore them after the tests
                original_get_page = get_page
      
                get_page = func(url string) string {
                    if url != "expected" {
                        t.Fatal("good message")
                    }
                    return "something"
                }
                downloader()
                t.Cleanup(func() }
                  get_page = original_get_page
                })
      }
      
      What if we have to mock the function more than once for a single test case?
      func TestDownloader(t *testing.T) {
      
                // Backup original functions. We need to restore them after the tests
                original_get_page = get_page
      
                var callCount int
                get_page = func(url string) string {
                    callCount++
                    switch callCount {
                    case 1:
                        return "something from the first call"
                    case 2:
                        return "something from the second call"
                    case 3:
                        return "something from the third call"
                    case 4:
                        return "something from the fourth call"
                    default:
                        return fmt.Errorf("unexpected call to get_page")
                    }
                }
                downloader()
                t.Cleanup(func() }
                  get_page = original_get_page
                })
      }
      

Links to this note