簡體   English   中英

嵌套結構的Golang單元測試Mock方法

[英]Golang Unit Test Mock method of nested struct

我想模擬一個嵌套結構的方法。 我試圖定義一個接口並讓 Mock 實現它,但我無法讓它工作。

這是我要測試的結構:

type OuterThing struct {
    innerThing *InnerThing
}

func (a *OuterThing) doLotsOfStuff() {
    println("i am doing")
    u, err := a.innerThing.DoStuff("lots of stuff")
    if err != nil {
        println("ran into an error, also doing some logic")
    }
    println("and more", u)
}

我想模擬它的DoStuff() function 的嵌套結構如下所示:

type InnerThing struct {
    name string
}

func (b *InnerThing) DoStuff(x string) (uint64, error) {
    println("i want to mock this method")
    return 0, nil
}

有點扭曲:我不能更改這些結構及其方法的代碼。

為了讓我的觀點更清楚一點,我寫了這個測試:

func TestDoLotsOfStuff(t *testing.T) {
    testCases := []struct {
        name            string
        structUnderTest *OuterThing
    }{
        {
            name: "happy case",
            structUnderTest: &OuterThing{
                innerThing: &InnerThing{name: "I am the inner thing."},
            },
        },
        {
            name: "error case",
            structUnderTest: &OuterThing{
                innerThing: &InnerThing{name: "i should be a mock with a mocked DoStuff function"},
            },
        },
    }

    for _, testCase := range testCases {
        t.Run(testCase.name, func(t *testing.T) {
            testCase.structUnderTest.doLotsOfStuff()
            // assertions
        })
    }
}

我對 Java 和 Mockito 非常熟悉,這將是一項非常簡單的任務。 我知道 Go 與其隱式接口和沒有類等有很多差異,但這真的是一個不常見的用例嗎?

您可以通過使用接口和依賴注入來做到這一點。 假設您有一個名為Inner的接口,其中包含DoStuff()方法。 OuterThing結構應該包含這個接口而不是結構InnerThing 現在,您可以使用依賴注入將Inner接口傳遞給這個OuterThing結構。

type Inner interface {
    DoStuff(string) (uint64, error)
}

type OuterThing struct {
    innerThing Inner
}

func NewOuterThing(in Inner) *OuterThing {
    return &OuterThing{
        innerThing: in,
    }
}

現在,在測試中,您可以創建mockInnerThing結構並實現模擬DoStuff()方法並將mockInnerThing傳遞給OuterThing結構。

type MockInnerThing struct {
    name string
}

func NewMockInnerThing(name string) *MockInnerThing {
    return &MockInnerThing{
        name: name,
    }
}

func (b *MockInnerThing) DoStuff(x string) (uint64, error) {
    println("Mock!")
    return 0, nil
}
func TestDoLotsOfStuff(t *testing.T) {
    mit := NewMockInnerThing("Test")
    ot := NewOuterThing(mit)
    ot.doLotsOfStuff()
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM