gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 02:04:55 25 4
gpt4 key购买 nike

我正在使用没有任何类接口(interface)的第三方库。我可以在我的结构中使用它们没问题,但它们有副作用,我想在单元测试时避免。

// 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())
}

这行得通!但是我想写一些单元测试,所以我想模拟这两个第三方结构。为此,我相信我需要它们的接口(interface),但由于 ThirdPartyFetcher 返回 ThirdPartyEntrys,我不知道如何做。

我创建了一对与两个第三方类匹配的接口(interface)。然后我想重写 Awesome 结构和方法以使用通用的 Fetcher 接口(interface)。在我的测试中,我会调用 NewAwesome() 传递一个 testFetcher,一个也实现接口(interface)的结构。

type Awesome struct {
F Fetcher
}
func NewAwesome(fetcher Fetcher) Awesome {
return Awesome{
Fetcher: fetcher,
}
}

type Entry interface {
Resolve() string
}
// Double check ThirdPartyEntry implements Entry
var _ Entry = (*ThirdPartyEntry)(nil)

type Fetcher interface {
FetchEntry() Entry
}
// Double check ThirdPartyFetcher implements Fetcher
var _ Fetcher = (*ThirdPartyFetcher)(nil)

我省略了测试代码,因为它不相关。这在显示的最后一行失败。

./main.go:49: cannot use (*ThirdPartyFetcher)(nil) (type *ThirdPartyFetcher) as type Fetcher in assignment:
*ThirdPartyFetcher does not implement Fetcher (wrong type for FetchEntry method)
have FetchEntry() ThirdPartyEntry
want FetchEntry() Entry

签名是不同的,尽管我已经展示了 ThirdPartyEntry 实现了 Entry。我相信这是不允许的,因为这会导致像 slice 这样的事情(在多态意义上,而不是 golang 意义上)。有没有办法让我写一对接口(interface)?应该是这样的情况,Awesome 类甚至不知道 ThirdParty 的存在——它在接口(interface)后面被抽象,并在 main 调用 NewAwesome 时注入(inject)。

最佳答案

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

type fetcherWrapper struct {
ThirdPartyFetcher
}

func (fw fetcherWrapper) FetchEntry() Entry {
return fw.ThirdPartyFetcher.FetchEntry()
}

我想说模拟返回结构与接口(interface)的东西是一个相对常见的问题,除了大量的中间包装之外没有任何好的解决方案。

关于testing - 当一个具体方法的签名引用另一个具体类型而不是它的接口(interface)时,我如何模拟多个类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33684030/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com