Behauptung: Mock: Ich weiß nicht, was ich zurückgeben soll, da der Methodenaufruf unerwartet war. Fehler beim Schreiben des Komponententests in Go

王林
Freigeben: 2024-02-10 09:00:18
nach vorne
494 Leute haben es durchsucht

断言:模拟:我不知道要返回什么,因为方法调用是意外的 在 Go 中编写单元测试时出错

In diesem Artikel stellt Ihnen der PHP-Editor Xiaoxin einen häufigen Fehler vor, der beim Schreiben von Unit-Tests in der Go-Sprache auftritt, nämlich Assertionsfehler. Wenn wir Unit-Tests schreiben, stoßen wir manchmal auf Situationen, in denen der Rückgabewert nicht ermittelt werden kann, was zu unerwarteten Fehlern beim Methodenaufruf führen kann. In diesem Artikel besprechen wir die Ursachen und Lösungen für dieses Problem, um Ihnen dabei zu helfen, Assertionsfehler besser zu bewältigen und die Genauigkeit und Zuverlässigkeit Ihrer Unit-Tests sicherzustellen.

Frageninhalt

Ich schreibe Unit-Tests für meine Servicemethoden in go using testify und alle Methoden funktionieren einwandfrei, außer der Update-Methode, da ich in der Update-Methode eine andere Methode desselben Dienstes in der Update-Methode aufrufe (" getbyid") .

Aktualisierungsmethode in meinem Dienst implementieren:

func (ts *teamservice) update(team *team.team) apperror {
    t, err := ts.teamrepo.getbyid(team.id)
    if err != nil {
        return err
    }
    if t.teamownerid != team.teamownerid {
        return newforbiddenerror(forbiddenerr)
    }

    return ts.teamrepo.update(team)
}
Nach dem Login kopieren

Mockrepo-Update-Methode:

func (t *teamrepomock) update(team *team.team) apperror {
    args := t.called(team)
    if args.error(0) != nil {
        return newnotfounderror(args.error(0))
    }

    return nil
}
Nach dem Login kopieren

Durchführung von Tests:

func testupdate(t *testing.t) {
    _, teamidgen, playeridgen := setupconfig()

    t.run("update a team", func(t *testing.t) {
        teamrepo, _, ts := setupteamservice(teamidgen, playeridgen)

        teamrepo.on("update", testteam1).return(nil)
        result := ts.update(testteam1)

        assert.nil(t, result)
    })

    t.run("update a team fails", func(t *testing.t) {
        teamrepo, _, ts := setupteamservice(teamidgen, playeridgen)

        expected := oopserr
        teamrepo.on("update", testteam1).return(expected)
        result := ts.update(testteam1)

        assert.equalvalues(t, expected.error(), result.error())
    })
}
Nach dem Login kopieren

Wenn ich jetzt den Test durchführe, erhalte ich die folgende Fehlermeldung:

--- FAIL: TestUpdate (0.01s)
    --- FAIL: TestUpdate/Update_a_team (0.01s)
panic: 
assert: mock: I don't know what to return because the method call was unexpected.
    Either do Mock.On("GetByID").Return(...) first, or remove the GetByID() call.
    This method was unexpected:
        GetByID(string)
        0: ""
    at: [/home/waleem/Desktop/project/eazykhel_server/services/teamservice/team_service_init_test.go:18 /home/waleem/Desktop/project/eazykhel_server/services/teamservice/team_service.go:146 /home/waleem/Desktop/project/eazykhel_server/services/teamservice/team_service_test.go:277] [recovered]
    panic:
Nach dem Login kopieren

Ich habe versucht, .on("update") vor und nach dem Aufruf von mock.on("getbyid") in der Testfunktionsimplementierung aufzurufen, aber es funktioniert nicht und ich Ich habe auch die Mockrepo-Update-Funktion geändert, aber es hat nicht funktioniert. .on("update") 之前和之后调用 mock.on("getbyid") ,但它不起作用,而且我还修改了mockrepo update函数,但它没用。

解决方法

让我尝试帮助您解决问题。我通过一些简化复制了该存储库,只是为了发布相关代码。如果我在您的解决方案中没有错,有一个服务(teamservice)调用底层包(teamrepo)提供的一些方法。您想测试 teamservice 结构的 update

Lösung

repo/repo.goLassen Sie mich versuchen, Ihnen bei der Lösung Ihres Problems zu helfen. Ich habe das Repository mit einigen Vereinfachungen kopiert, nur um den relevanten Code zu veröffentlichen. Wenn ich mich mit Ihrer Lösung nicht irre, gibt es einen Dienst (teamservice), der einige Methoden aufruft, die vom zugrunde liegenden Paket (teamrepo) bereitgestellt werden. Sie möchten die Methode update der Struktur teamservice testen. Lassen Sie mich nach der Überprüfung zunächst den Code zeigen und dann versuchen, jede Datei zu erklären:

getbyidupdate

package repo

type team struct {
    id          int
    teamownerid int
    name        string
}

type teamrepo struct{}

func (t *teamrepo) getbyid(id int) (team, error) {
    return team{id: id, teamownerid: id, name: "myteam"}, nil
}

func (t *teamrepo) update(team team) error {
    return nil
}
Nach dem Login kopieren

In dieser Datei finden wir die zu simulierende Methode. Die Methode ist: services/service.go. Offensichtlich ist dies nicht Ihr tatsächlicher Code, aber das spielt im Moment keine Rolle.

sut)。通过依赖注入,我们将利用通过接口 teamrepointerface 注入的 repo

package services

import (
    "errors"

    "testifymock/repo"
)

type teamservice struct {
    tr teamrepointerface
}

func newteamservice(repo teamrepointerface) *teamservice {
    return &teamservice{
        tr: repo,
    }
}

type teamrepointerface interface {
    getbyid(id int) (repo.team, error)
    update(team repo.team) error
}

func (ts *teamservice) update(team *repo.team) error {
    t, err := ts.tr.getbyid(team.id)
    if err != nil {
        return err
    }

    if t.teamownerid != team.teamownerid {
        return errors.new("forbidden")
    }

    return ts.tr.update(*team)
}
Nach dem Login kopieren

Hier können wir im Testcode die Dienste (services/service_test.go vom Paket bereitgestellte Funktionen) sehen, die zu unserem getesteten System werden

package services

import (
    "errors"
    "testing"

    "testifymock/repo"

    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/mock"
)

// 1. declare the mock struct
type teamRepoMock struct {
    mock.Mock
}

// 2. implement the interface
func (m *teamRepoMock) GetByID(id int) (repo.Team, error) {
    args := m.Called(id)

    return args.Get(0).(repo.Team), args.Error(1)
}

func (m *teamRepoMock) Update(team repo.Team) error {
    args := m.Called(team)

    return args.Error(0)
}

func TestUpdate(t *testing.T) {
    t.Run("GoodUpdate", func(t *testing.T) {
        // 3. instantiate/setup mock
        repoMock := new(teamRepoMock)
        repoMock.On("GetByID", 1).Return(repo.Team{ID: 1, TeamOwnerID: 1, Name: "test"}, nil).Times(1)
        repoMock.On("Update", repo.Team{ID: 1, TeamOwnerID: 1, Name: "test"}).Return(nil).Times(1)

        sut := NewTeamService(repoMock)
        err := sut.Update(&repo.Team{ID: 1, TeamOwnerID: 1, Name: "test"})

        // 4. check that all expectations were met on the mock
        assert.Nil(t, err)
        assert.True(t, repoMock.AssertExpectations(t))
    })

    t.Run("BadUpdate", func(t *testing.T) {
        // 3. instantiate/setup mock
        repoMock := new(teamRepoMock)
        repoMock.On("GetByID", 1).Return(repo.Team{ID: 1, TeamOwnerID: 1, Name: "test"}, nil).Times(1)
        repoMock.On("Update", repo.Team{ID: 1, TeamOwnerID: 1, Name: "test"}).Return(errors.New("some error while updating")).Times(1)

        sut := NewTeamService(repoMock)
        err := sut.Update(&repo.Team{ID: 1, TeamOwnerID: 1, Name: "test"})

        // 4. check that all expectations were met on the mock
        assert.Equal(t, "some error while updating", err.Error())
        assert.True(t, repoMock.AssertExpectations(t))
    })
}
Nach dem Login kopieren
repomock.on("getbyid", 1).return(repo.team{id: 1, teamownerid: 1, 姓名: "test"}, nil).times(1)Im Code finden Sie einige Kommentare, um das Geschehen genauer zu beschreiben. Wie Sie sich vorstellen können, besteht das Problem darin, dass dieser Aufruf im Code fehlt:


🎜Wenn Sie meine Lösung ausführen, sollte sie auch für Sie funktionieren. 🎜 Wenn dies Ihr Problem löst oder Sie weitere Fragen haben, lassen Sie es mich bitte wissen! 🎜

Das obige ist der detaillierte Inhalt vonBehauptung: Mock: Ich weiß nicht, was ich zurückgeben soll, da der Methodenaufruf unerwartet war. Fehler beim Schreiben des Komponententests in Go. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!