Thursday, October 12, 2017

在 Golang 裡使用類似 Clojure 的 with-redefs 技巧

在寫 Golang 的 unit test 的時候,我覺得很不方便的一點就是沒有辦法像 clojure 一樣,利用 with-redefs 將 symbol 重新定義,讓本來有外部依賴的函數可以很快地被測試。但是,公司的資深工程師 Mike 教了我一招。

基本的概念就是這樣子:
1. 在 Golang 裡,可以被重新定義的東西就是 global variable 。
2. 如果要測的某個函數,它本身沒有寫好依賴注入之類的東西,又恰好呼叫了一個有 complex dependency 的函數。就把這個有 complex dependency 的函數用 global variable 來加上一層間接性。
package main
import "fmt"
func bar() {
fmt.Println("bar is a function with complex dependency")
}
var bar_impl func() = bar
func foo() {
bar_impl()
}
view raw main.go hosted with ❤ by GitHub
package main
import (
"fmt"
"testing"
)
func simple() {
fmt.Println("simple dependency.")
}
func init() {
// golang version of with-redefs
bar_impl = simple
}
func TestFoo(t *testing.T) {
foo()
}
view raw mian_test.go hosted with ❤ by GitHub