英文:
How to Mock inner methods in GoLang
问题
你好!以下是翻译好的内容:
type test struct { // 几个字段 }
func (t *test) createresource(res1 string, res2 string) error {
// 执行一些任务
t.createsubresource(res1)
}
func (t *test) createsubresource(res1 string) error {
// 执行一些任务
}
我想为createresource
编写测试函数,如何模拟 t.createsubresource(res1)
的调用?这是旧代码,我没有权限修改上面的任何函数。
英文:
e.g
type test struct { // few fields}
func (t *test) createresource(res1 string,res2 string)error {
//doing some task
t.createsubresource(res1)
}
func (t *test)createsubresource(res1 string)error{
//perform some task
}
I want to write test function for createresource , how can I mock t.createsubresource(res1) call. This is legacy code and I don't have permission to modify any above function.
答案1
得分: 5
你可以使用接口来模拟,例如:
main.go
package main
type TestInterface interface {
CreateResource(res1 string, res2 string) error
CreateSubresource(res1 string) error
}
func main() {
DoSomething(new(Test))
}
func DoSomething(t TestInterface) {
t.CreateResource()
}
main_test.go
package main
import "testing"
type TestMock struct {}
func (tm *TestMock) CreateResource(res1 string, res2 string) error {
return nil
}
func (tm *TestMock) CreateSubresource(res1 string) error {
return nil
}
func TestDoSomething(t *testing.T) {
err := DoSomething(new(TestMock))
//... do your assertions
}
为什么要这样做?
调用依赖于特定结构的函数不允许您注入替代品,因此需要创建一个使用接口的解决方案。通过拥有一个接口,只需实现一个与该接口匹配的新结构,并将其作为依赖注入传递给将被测试的过程。
另外,请查看以下内容:
- 默认情况下,没有简单的方法可以指向您的原始结构并告诉Go从中创建一个模拟。也许有一些第三方库可以做到这一点(但我还没有看到)。
- 在Go中,公共和私有声明由首字母大写来定义。通过您示例中的小写声明,我注意到所有内容都是私有的。
- 通常不建议测试私有方法。关于这个话题有很多讨论,你可以看看这个。
- 还有一些支持断言和模拟的库,例如stretchr/testify,请先进行一些研究。
希望对你有所帮助。
英文:
Your mock can be done using interfaces, as for example:
main.go
package main
type TestInterface interface {
CreateResource(res1 string, res2 string) error
CreateSubresource (res1 string) error
}
func main() {
DoSomething(new(Test))
}
func DoSomething(t TestInterface) {
t.CreateResource()
}
main_test.go
package main
import "testing"
type TestMock struct {}
func (tm *TestMock) CreateResource(res1 string, res2 string) error {
return nil
}
func (tm *TestMock) CreateSubresource(res1 string) error {
return nil
}
func TestDoSomething(t *testing.T) {
err := DoSomething(new(TestMock))
//... do your assertions
}
Why does it works like that?
Calling a function that depends on a specific structure does not allow you to inject alternatives to it, that's why a solution using interface needs to be created. By having an interface, just implement a new structure that matches that interface and pass it as a dependency injection to the procedure that will be tested.
Also, check this out:
- There is no easy way, by default, to just point your original structure and tell Go to make a mock from it. Maybe some 3rd party lib can do it (but I didn't saw that yet).
- In go, public and private declarations are defined by the first letter as uppercase. By the lower cases declarations in your sample I've noticed that everything is private.
- Usually it is not a good practice to test private methods. There are a lot of discussions about this topic, you can take a look in this one here
- There are also some support libs to make assertions and mocks like for example stretchr/testify, please make a research first.
I hope that it helps you.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论