[英]Go mocking with interfaces for testing
我對 Go 很陌生,而且我來自 OOP 語言。 現在這個概念在接口和類的 go 中似乎完全不同。
我想知道 mocking 在測試的情況下如何工作。 我遇到的困惑是是否可以將struct
用作類,如果下面的方法是你想怎么做的? 假設DefaultArticlesRepository
用於真實數據,而MockArticlesRepository
用於 mocking 它。
type ArticlesRepository interface {
GetArticleSections() []ArticleSectionResponse
}
type DefaultArticlesRepository struct{}
type MockArticlesRepository struct{}
func (repository DefaultArticlesRepository) GetArticleSections() []ArticleSectionResponse {
return []ArticleSectionResponse{
{
Title: "Default response",
Tag: "Default Tag",
},
}
}
func (repository MockArticlesRepository) GetArticleSections() []ArticleSectionResponse {
return []ArticleSectionResponse{
{
Title: "Mock response",
Tag: "Mock Tag",
},
}
}
func ArticleSectionsProvider(v ArticlesRepository) ArticlesRepository {
return v
}
func TestFoo(t *testing.T) {
realProvider := ArticleSectionsProvider(DefaultArticlesRepository{})
mockProvider := ArticleSectionsProvider(MockArticlesRepository{})
assert.Equal(t, realProvider.GetArticleSections(), []ArticleSectionResponse{
{
Title: "Default response",
Tag: "Default Tag",
},
})
assert.Equal(t, mockProvider.GetArticleSections(), []ArticleSectionResponse{
{
Title: "Mock response",
Tag: "Mock Tag",
},
})
}
首先,我建議你使用https://github.com/vektra/mockery來根據接口自動生成模擬結構。 實現一個像你這樣的模擬結構是可以的,但我認為如果你真的不需要該結構的非常特殊的行為,那只會浪費你的時間和精力。
其次,我們不需要像您在代碼中那樣測試模擬結構。
assert.Equal(t, mockProvider.GetArticleSections(), []ArticleSectionResponse{
{
Title: "Mock response",
Tag: "Mock Tag",
},
})
因此,當我們使用模擬結構時,假設 struct a是 struct b的依賴項。 例如:
type A interface {
DoTask() bool
}
type a struct {}
func (sa *a) DoTask() bool {
return true
}
type b struct {
a A
}
func (sb *b) DoSomething() bool {
//Do some logic
sb.a.DoTask();
//Do some logic
return true;
}
並且您想測試 struct b的 function DoSomething 。 當然,在這種情況下,您不關心也不想測試結構a的 function DoTask。 然后,您只需在測試中提供 struct a到 struct b的模擬。 這個模擬還可以幫助您避免在測試 struct b時處理與 struct a相關的任何問題。 現在你的測試應該是這樣的:
func (s *TestSuiteOfStructB) TestDoSomething_NoError() {
//Suppose that mockedOfA is a mock of struct a
instanceOfB := b{a: mockedOfA}
mockedOfA.On("DoTask").Return(true)
actualResult := instanceOfB.DoSomething()
s.Equal(true, actualResult)
}
最后,這只是一件小事,但看不到您的ArticleSectionsProvider的明確責任。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.