unit-testing - 使用接口进行模拟以进行测试
问题描述
我对 Go 很陌生,而且我来自 OOP 语言。现在,接口和类的概念似乎完全不同。
我想知道在测试的情况下模拟将如何工作。我的困惑是是否可以struct
用作一个类,如果下面的方法是你想怎么做的?假设这DefaultArticlesRepository
将用于真实数据并MockArticlesRepository
用于模拟它。
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的功能 DoSomething 。当然,在这种情况下,您不关心也不想测试 struct a的函数 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的明确责任。
推荐阅读
- python - Python 的 sys.stdout.buffer.write() 在 Linux 上增加了额外的 0x0d
- python-3.x - Keras Xception 模型输入形状混淆
- java - 在 Selenium - Java 中从屏幕(虚拟键盘)输入键盘键
- javascript - ReactJs: can't access object element
- maven - SpotBugs 和 Maven 与 Linux 机器使用 excludeFilterFile 和插件配置失败
- css - 如何为目录分页添加样式
- amazon-web-services - Nifi GetSQS 访问被拒绝 - AWS 简单队列服务
- c# - 将参数传递给 RestSharp GET 请求
- javascript - 我的段落中有分栏吗?里面有多少行?
- visual-studio - 在 Windows 10 Visual Studio 2017 上从 cmake 构建 OpenCV 编译错误