Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go: test internal functions

Suppose I have a type MyType with a private method (mt *MyType) private() in a package mypackage. I also have a directory tests, where I want to store tests for my package. This is how tests/mypackage_test.go looks like:

package mypackage_test

import (
    "testing"
    "myproj/mypackage"
)

func TestPrivate(t *testing.T) {
    // Some test code
}

However, when I run go test I get the cannot refer to unexported field or method my package.(*MyType)."".private) error. I've googled a bit and found out that functions starting with lower case can not be seen outside their own package (and this seems to be true, 'cause upper case functions are freely callable from the tests).

I also read somewhere that adding <...>_internal_test.go to the test file could solve my problem like this (tests/mypackage_internal_test.go):

package mypackage

import (
    "testing"
)

func TestPrivate(t *testing.T) {

    mt := &MyType{}
    // Some test code
}  

But with this I only get undefined: MyType. So, my question: how can I test internal/private methods?

like image 769
oopcode Avatar asked Dec 10 '22 21:12

oopcode


2 Answers

Why do you place your tests in a different package? The go testing mechanism uses _test as a suffix for test files so you can place tests in the same packages as the actual code, avoiding the problem you describe. Placing tests in a separate package is not idiomatic Go. Do not try to fight the Go conventions, it's not worth the effort and you are mostly going to lose the fight.

like image 60
fuz Avatar answered Dec 29 '22 19:12

fuz


Go insists that files in the same folder belong to the same package, that is except for _test.go files. Moving your test code out of the package allows you to write tests as though you were a real user of the package. You cannot fiddle around with the internals, instead you focus on the exposed interface and are always thinking about any noise that you might be adding to your API.

And:

If you do need to unit test some internals, create another file with _internal_test.go as the suffix. Internal tests will necessarily be more brittle than your interface tests — but they’re a great way to ensure internal components are behaving, and are especially useful if you do test-driven development.

Source: https://medium.com/@matryer/5-simple-tips-and-tricks-for-writing-unit-tests-in-golang-619653f90742

There are different opinions on how you should struct you tests within a golang project and I suggest you to read the blog above.

like image 30
db80 Avatar answered Dec 29 '22 20:12

db80