为了账号安全,请及时绑定邮箱和手机立即绑定

当一个具体方法的签名引用另一个具体类型而不是它的接口时,如何模拟多个类型?

当一个具体方法的签名引用另一个具体类型而不是它的接口时,如何模拟多个类型?

Go
哈士奇WWW 2021-11-22 15:43:43
我正在使用一个第三方库,它的类没有任何接口。我可以在我的结构中使用它们没问题,但它们有副作用,我想在单元测试时避免这些副作用。// Somewhere there are a couple structs, with no interfaces. I don't own the code.// Each has only one method.type ThirdPartyEntry struct {}func (e ThirdPartyEntry) Resolve() string {    // Do some complex stuff with side effects    return "I'm me!"}// This struct returns an instance of the other one.type ThirdPartyFetcher struct {}func (f ThirdPartyFetcher) FetchEntry() ThirdPartyEntry {    // Do some complex stuff with side effects and return an entry    return ThirdPartyEntry{}}// Now my code.type AwesomeThing interface {    BeAwesome() string}// I have a class that makes use of the third party.type Awesome struct {    F ThirdPartyFetcher}func (a Awesome) BeAwesome() string {    return strings.Repeat(a.F.FetchEntry().Resolve(), 3)}func NewAwesome(fetcher ThirdPartyFetcher) Awesome {    return Awesome{        F: fetcher,    }}func main() {    myAwesome := NewAwesome(ThirdPartyFetcher{})    log.Println(myAwesome.BeAwesome())}这有效!但是我想写一些单元测试,所以我想模拟这两个第三方结构。为此,我相信我需要它们的接口,但由于 ThirdPartyFetcher 返回 ThirdPartyEntrys,我无法弄清楚如何。我创建了一对与两个第三方类匹配的接口。然后我想重写 Awesome 结构和方法以使用通用 Fetcher 接口。在我的测试中,我会调用 NewAwesome() 传入一个 testFetcher,一个也实现接口的结构。type Awesome struct {    F Fetcher}func NewAwesome(fetcher Fetcher) Awesome {    return Awesome{        Fetcher: fetcher,    }}type Entry interface {    Resolve() string}// Double check ThirdPartyEntry implements Entryvar _ Entry = (*ThirdPartyEntry)(nil)type Fetcher interface {    FetchEntry() Entry}// Double check ThirdPartyFetcher implements Fetchervar _ Fetcher = (*ThirdPartyFetcher)(nil)签名是不同的,即使我已经展示了 ThirdPartyEntry 实现了 Entry。我相信这是不允许的,因为 to 会导致切片之类的东西(在多态意义上,而不是 golang 意义上)。有没有办法让我写一对接口?应该是这样的情况,Awesome 类甚至不知道 ThirdParty 存在——它被抽象在接口后面,并在 main 调用 NewAwesome 时注入。
查看完整描述

1 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

它不是很漂亮,但一种方法是:


type fetcherWrapper struct {

    ThirdPartyFetcher

}


func (fw fetcherWrapper) FetchEntry() Entry {

    return fw.ThirdPartyFetcher.FetchEntry()

}

我会说嘲笑返回结构与接口的东西是一个相对常见的问题,除了很多中间包装之外没有任何很好的解决方案。


查看完整回答
反对 回复 2021-11-22
  • 1 回答
  • 0 关注
  • 150 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信