Win*_*ito 1 interface mocking go gomock
我正在尝试在 Go 中模拟 net.Interface,我使用 net.Interfaces() 并且我想要一个固定的回报。但 net.Interface 不是一个接口,所以我不能用 gomock 来模拟它。
\n也许我的测试方式是错误的。
\n这是我要测试的方法:
\nconst InterfaceWlan = "wlan0"\nconst InterfaceEthernet = "eth0"\n\nvar netInterfaces = net.Interfaces\n\nfunc GetIpAddress() (net.IP, error) {\n // On r\xc3\xa9cup\xc3\xa8re la liste des interfaces\n ifaces, err := netInterfaces()\n if err != nil {\n return nil, err\n }\n\n // On parcours la liste des interfaces\n for _, i := range ifaces {\n // Seul l\'interface Wlan0 ou Eth0 nous int\xc3\xa9resse\n if i.Name == InterfaceWlan || i.Name == InterfaceEthernet {\n // On r\xc3\xa9cup\xc3\xa8re les adresses IP associ\xc3\xa9 (g\xc3\xa9n\xc3\xa9ralement IPv4 et IPv6)\n addrs, err := i.Addrs()\n\n // Some treatments on addrs...\n }\n }\n\n return nil, errors.New("network: ip not found")\n}\nRun Code Online (Sandbox Code Playgroud)\n这是我暂时写的测试
\nfunc TestGetIpAddress(t *testing.T) {\n netInterfaces = func() ([]net.Interface, error) {\n // I can create net.Interface{}, but I can\'t redefine \n // method `Addrs` on net.Interface\n }\n \n address, err := GetIpAddress()\n if err != nil {\n t.Errorf("GetIpAddress: error = %v", err)\n }\n\n if address == nil {\n t.Errorf("GetIpAddress: errror = address ip is nil")\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n最小可重现示例:
\n\n您可以使用方法表达式net.Interfaces将方法绑定到函数类型的变量,这与将函数绑定到变量的方式大致相同:
var (\n netInterfaces = net.Interfaces\n netInterfaceAddrs = (*net.Interface).Addrs\n)\n\nfunc GetIpAddress() (net.IP, error) {\n \xe2\x80\xa6\n // Get IPs (mock method Addrs ?)\n addrs, err := netInterfaceAddrs(&i)\n \xe2\x80\xa6\n}\nRun Code Online (Sandbox Code Playgroud)\n然后,在测试中,您可以用相同的方式更新绑定:
\nfunc TestGetIpAddress(t *testing.T) {\n \xe2\x80\xa6\n netInterfaceAddrs = func(i *net.Interface) ([]net.Addr, error) {\n return []net.Addr{}, nil\n }\n \xe2\x80\xa6\n}\nRun Code Online (Sandbox Code Playgroud)\n(https://play.golang.org/p/rqb0MDclTe2)
\n也就是说,我建议将模拟方法分解为结构类型,而不是覆盖全局变量。这允许测试并行运行,并且还允许包的下游用户编写自己的测试,而无需改变全局状态。
\n// A NetEnumerator enumerates local IP addresses.\ntype NetEnumerator struct {\n Interfaces func() ([]net.Interface, error)\n InterfaceAddrs func(*net.Interface) ([]net.Addr, error)\n}\n\n// DefaultEnumerator returns a NetEnumerator that uses the default\n// implementations from the net package.\nfunc DefaultEnumerator() NetEnumerator {\n return NetEnumerator{\n Interfaces: net.Interfaces,\n InterfaceAddrs: (*net.Interface).Addrs,\n }\n}\n\nfunc GetIpAddress(e NetEnumerator) (net.IP, error) {\n \xe2\x80\xa6\n}\nRun Code Online (Sandbox Code Playgroud)\n(https://play.golang.org/p/PLIXuOpH3ra)
\n