[英]issue with dependency injection with interface
我有提供与tcp连接一起工作的软件包,基本上是这样的:
package connpool
import (
"io/ioutil"
"net/http"
)
type ConnPool struct{}
func (pool *ConnPool) GetConn() Conn {
return Conn{}
}
func (pool *ConnPool) ReleaseConnection(conn Conn) {
}
type Conn struct{}
func (c Conn) FetchUrl(url string) ([]byte, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return []byte{}, err
}
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
return body, nil
}
然后我尝试在另一个程序包中使用它,但按接口将其包装起来,因为我想用假connpool在测试环境中替换此程序包
package main
import (
"connpool"
"fmt"
)
func onlyDependencyOnConnPool() *connpool.ConnPool {
return &connpool.ConnPool{}
}
type ConnPoolInterface interface {
GetConn() ConnInterface
ReleaseConnection(ConnInterface)
}
type ConnInterface interface {
FetchUrl(string) ([]byte, error)
}
type Fetcher struct{}
func (f Fetcher) Fetch(cPool ConnPoolInterface) error {
conn := cPool.GetConn()
defer cPool.ReleaseConnection(conn)
body, err := conn.FetchUrl("http://localhost:9200")
fmt.Println("body: ", string(body))
return err
}
func main() {
pool := onlyDependencyOnConnPool()
f := Fetcher{}
f.Fetch(pool)
}
但是它将在编译时返回错误:
./main.go:34: cannot use pool (type *connpool.ConnPool) as type ConnPoolInterface in argument to f.Fetch:
*connpool.ConnPool does not implement ConnPoolInterface (wrong type for GetConn method)
have GetConn() connpool.Conn
want GetConn() ConnInterface
有没有办法在每个文件中没有connpool导入的情况下通过接口包装此依赖项?
我只需要它来模拟测试环境中的http请求,就像这样(如果我要在connpool包中实现接口,则我必须在其中实现每个模拟结构,看起来就像是一团糟):
package main
import(
"testing"
)
type FakeConnPool struct{}
func (pool *FakeConnPool) GetConn() FakeConn {
return FakeConn{}
}
func (pool *FakeConnPool) ReleaseConnection(conn FakeConn) {
}
type FakeConn struct{}
func (c FakeConn) FetchUrl(url string) ([]byte, error) {
println(url)
body := []byte(`{"status" : 200}`)
return body, nil
}
func changeDependency() ConnPoolInterface {
return &FakeConnPool{}
}
func TestBaz(t *testing.T) {
pool := changeDependency()
f := Fetcher{}
err := f.Fetch(pool)
if err != nil {
t.Errorf("error")
}
}
第一步,将您对GetConn
的声明稍微更改为以下内容:
func (pool *ConnPool) GetConn() ConnInterface { // Conn -> ConnInterface
return Conn{}
}
那应该满足ConnPoolInterface
的接口。 您可能必须稍稍重新排列代码,以免之后出现循环依赖。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.