如何在Golang中模拟struct方法

时间:2018-01-10 02:46:10

标签: unit-testing go mocking

我正在阅读此页面(我没有使用亚马逊,只是阅读golang教育)

https://aws.amazon.com/blogs/developer/mocking-out-then-aws-sdk-for-go-for-unit-testing/

当我为自己尝试时,我会遇到类型错误。

type Queue struct {
    Client ThirdPartyStruct
    URL    string
}

type mockedReceiveMsgs struct {
    ThirdPartyStruct
    Resp ValueIWantToMock
}

q := Queue{Client: mockedReceiveMsgs{}}

当我尝试做同样的事情时,我得到了

cannot use mocked literal (type mockedReceiveMsgs) as type ThirdPartyStruct in field value

我觉得我正在完全复制亚马逊教程。为什么有代码,mockedReceiveMsgs可以用来代替ThirdPartyStruct?

2 个答案:

答案 0 :(得分:1)

问题不在于模拟,而在于Queue结构按值包含ThirdPartyStruct(作为子结构),而不是指针。 mockedReceiveMsgs也是如此。恰好在Queue结构中,这个子结构可以通过客户端名称访问,而在mockedReceiveMsgs中,它应该是“匿名的”(但如果需要,实际上可以通过ThirdPartyStruct名称引用)。

因此,q := Queue{Client: mockedReceiveMsgs{}}实际上尝试将mockedReceiveMsgs复制到Client中,它显然会失败,因为它有额外的位,不适合ThirdPartyStruct。您可以通过将其更改为q := Queue{Client: mockedReceiveMsgs{}.ThirdPartyStruct}进行编译,但我怀疑这是您想要的。

请注意,如果您将Client ThirdPartyStruct更改为Client interface{}(在原始示例中),那么它也会进行编译。这很可能是你想要的。它也适用于任何接口类型。这是@tkausl最有可能指出的内容。当您实现接口时,唯一棘手的一点是指针语义与值语义。它有时会起火。请参阅快速示例here

答案 1 :(得分:0)

如果名称ThirdPartyStructstruct类型而不是interface类型,那么你就不能嘲笑它,这在Go中是不可能的。如果您仔细阅读示例文章并按照SQSAPI的{​​{3}}进行操作,则会看到它是interface类型。

type SQSAPI interface {

要使代码“可模拟”,您需要使用Client字段的接口类型。这是一个更为真实的例子:link that shows the definition