1

Having issue creating unit test of one of my source file ( commonutil.go )

package util

import "github.com/nu7hatch/gouuid"

// GenerateUUID Returns generated UUID sequence
func GenerateUniqueID(hostname string) (string, error) {
    var result, err = uuid.NewV4()
    return hostname + ":" + result.String(), err
}

For the above source, I created the test file "commonutil_test.go" ( in the same package )

package util

import "testing" 
func TestCommonUtil(t *testing.T) {
t.Run("Test generate UUID", func(t *testing.T) {

    var uuid, _ = GenerateUniqueID ("test")
    //fmt.Printf("UUID isa %v \n", uuid)
    if uuid == "" {
        t.Errorf("UUID expected, but result is empty ")
    }
})

However when trying executing "go test util/commonutil_test.go" it shows :

util\commonutil_test.go:8: undefined: GenerateUniqueID
FAIL command-line-arguments [build failed]

Changing to util.GenerateUniqueID in the test solve the problem, however when running coverage using Goconvey will cause build failure :

can't load package: import cycle not allowed package rudygunawan.com/MyProject/HFLC-Go/util imports rudygunawan.com/MyProject/HFLC-Go/util

Any idea to solve this issue? I am confused.

Go version is go1.7.1 windows/386

Rudy
  • 7,008
  • 12
  • 50
  • 85

3 Answers3

1

Just realize it is a silly mistake. The package for the test should be "util_test". Putting the test in the separate package ( but still in the same folder) help solve import cycle issue, yet still allow to solve the undefined error.

Rudy
  • 7,008
  • 12
  • 50
  • 85
  • No, the test files should generally have the same package name. You need to test the package as a whole, not individual files. – JimB Sep 28 '16 at 10:33
  • actually, not. Refer to the accepted answer of this http://stackoverflow.com/questions/19998250/proper-package-naming-for-testing-in-golang – Rudy Sep 28 '16 at 10:36
  • I said generally, the separate package pattern is very uncommon, and you haven't shown anything here to indicate that you require a special case for a separate package. The command you're running is incorrect, and you should be testing a package as a whole, rather than as individual files. – JimB Sep 28 '16 at 10:56
  • 2
    I tested the package as a whole. it still has the same issue. Anyway, the issue is gone after I separate the package. If you think this is a wrong approach, it would be helpful if you can suggest a way to work around my problem. – Rudy Sep 28 '16 at 10:59
  • What you have here isn't showing the problem, so it's hard to prescribe an exact solution.. The second error though indicates your package is trying to import itself. Remove the extra import and refer to the identifiers without the package name – JimB Sep 28 '16 at 11:21
1

The way I normally write Go unit tests is to have one (or more) ..._test.go files, in the same package as the code being tested, with one Test... function for each broad set of tests to be done.

package util

import "testing

func TestGenerateUniqueID(t *testing.T) {
   var uuid1, uuid2 string
   uuid1, err = GenerateUniqueID("test")
   if err != nil {
     t.Errorf("Expected no error, got %s", err) // Maybe Fatalf?
   }
   if uuid1 == "" {
     t.Errorf("Expected non-empty string, got empty string (uuid1)")
   }
   uuid2, err = GenerateUniqueID("test")
   if err != nil {
     t.Errorf("Expected no error, got %s", err) // Maybe Fatalf?
   }
   if uuid2 == "" {
     t.Errorf("Expected non-empty string, got empty string (uuid2)")
   }
   if uuid1 == uuid2 {
     t.Errorf("Expected uuid1 and uuid2 to be different, both are %s", uuid1)
   }
}

One of the reasons I tend towards whitebox testing (where I can do "blackbox testing" by carefully not accessing package internals) is that there's usually a whole slew of non-exported code that really should be tested as well. In this specific, small, example, there's no massive argument for one over the other, since all the functionality that can be tested is already exported.

Vatine
  • 20,782
  • 4
  • 54
  • 70
1

I've run into a similar problem, when I was trying to run a single test file.

I wanted that, as it was a kind of test driven development thing, where I wanted to run tests only for the code I was working on at the moment, and not all the x-minutes running tests.

The solution turned out to be not running tests from a file, but rather running a specific test by name (actually a regex). So in your case I guess it would be:

go test ./util -run TestCommonUtil

An alternative seems to be listing all the files needed to build your test code:

go test util/commonutil_test.go util/commonutil.go
fitek
  • 171
  • 1
  • 7