[英]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.