我有兴趣在Go中重新分配工厂函数以进行测试,以减少在想要模拟其中一种类型时在给定包中使用工厂函数的风险。
我见过人们将工厂函数作为参数传递给包含函数,并创建一个将工厂保存为数据成员的结构。是否可以保留顶级函数变量,并在某个给定文件中覆盖另一个实现?我试过以下内容:
type AirportFactory func (string, int, int) Airport
var makeAirport AirportFactory = func(n string, x int, y int) Airport {
return airport{name: n, pos: Position{X: x, Y: y}}
}
makeAirport = func(n string, x int, y int) Airport {
return airport{name:"default", pos:Position{X:0, Y:0}}
}
但是当我构建代码时,6g在最后一个赋值的结束行上给出了以下错误:
non-declaration statement outside function body
这使得函数类型的var
似乎是const,至少在顶层。有没有办法解决这个问题?
答案 0 :(得分:3)
他们不是一成不变的。您无法在函数外部分配已声明的变量。像这样的东西会起作用:
func changeAirport() {
makeAirport = func(n string, x int, y int) Airport {
return airport{name:"default", pos:Position{X:0, Y:0}}
}
}
就go而言,函数外部的变量赋值不会以任何特定顺序发生。因此,你只能做一次。
答案 1 :(得分:2)
您可以使用包init函数来设置包变量的模拟值。例如,
package main
import "fmt"
var x = 1
// set mock values of variables
func mock() {
x = 2
}
func init() {
mock()
}
func main() {
fmt.Println(x)
}
输出:
2
对于您的示例,
package main
import "fmt"
type Position struct {
X int
Y int
}
type Airport struct {
name string
pos Position
}
type AirportFactory func(string, int, int) Airport
var makeAirport AirportFactory = func(n string, x int, y int) Airport {
return Airport{name: n, pos: Position{X: x, Y: y}}
}
// set mock values of variables
func mock() {
makeAirport = func(n string, x int, y int) Airport {
return Airport{name: "default", pos: Position{X: 0, Y: 0}}
}
}
func init() {
mock()
}
func main() {
fmt.Println(makeAirport("name", 1, 1))
}
输出:
{default {0 0}}