How do I test error conditions, & other unexpected code flow, in Golang?
Suppose I have code as follows:
import crypto
func A(args) error {
x, err := crypto.B()
if err != nil {
return err
}
return nil
}
B
is some function. I believe that the only way for me to test this failure scenario is to change the value of B
for my test (mock it so it returns an error). Things I have tried:
1) monkeypatch the function just before the test and unpatch afterwards. This was a horrible idea. Caused all sorts of weird issues as the tests were running.
2) Pass B
as an argument to A
. This is all well and good but it also
means that I have to change the definition for A
and then update
every use of it every time the implementation changes. Furthermore,
A
may be using many imported functions and putting them all in the
type definition for A
just seems ugly and not idiomatic.
3) Change the value of B
for my test, then change it back.
import crypto.B
cryptoB = crypto.B
func A(args) error {
x, err := cryptoB()
if err != nil {
return err
}
...
}
func Test_A(t *testing.T) {
oldB := cryptoB
cryptoB = mockB
// run test
cryptoB = oldB
...
}
I've been using method #3 as it allows me fine grained unit testing control while not creating too much overhead. That said, it's ugly and causes confusion e.g. "Why are we renaming all of the imported functions?".
What should I be doing? Please help me so my codes can be more better :)