英文:
Mocking method from golang package
问题
我一直无法找到一种解决办法来对golang包中的方法进行模拟。
例如,我的项目中有一段代码,当Os.Getwd()返回错误时,尝试进行恢复。我能想到的最简单的方法是通过模拟Os.Getwd()方法返回一个错误,并验证代码是否按预期工作。
我尝试使用testify,但似乎不可能实现。
有人有相关经验吗?
英文:
I have been unable to find a solution to mocking methods from golang packages.
For example, my project has code that attempts to recover when Os.Getwd() returns an error. The easiest way I can thinking of making a unit test for this, is by mocking the Os.Getwd() method to return an error, and verify that the code works accordingly.
I tried using testify, but it does not seem to be possible.
Anyone have any experience with that?
答案1
得分: 3
我的解决方案是将方法作为参数传递,这样在测试时可以注入一个“mock”对象。此外,创建一个公共的导出方法作为外部接口,以及一个未导出的方法用于测试。
示例代码:
func Foo() int {
return foo(os.Getpid)
}
func foo(getpid func() int) int {
return getpid()
}
请注意,这只是一个示例,具体的实现可能因情况而异。
英文:
My own solution was to take the method as an argument, which allow to inject a "mock" instead when testing. Additionnaly, create an exported method as public facade and an unexported one for testing.
Example:
func Foo() int {
return foo(os.Getpid)
}
func foo(getpid func() int) int {
return getpid()
}
答案2
得分: 0
看起来查看一下os.Getwd测试可能会给你一些关于如何测试你的代码的示例。寻找函数TestChdirAndGetwd
和TestProgWideChdir
。
从阅读这些内容来看,测试会创建临时文件夹。
因此,一个实用的方法是创建临时文件夹,就像上面提到的测试那样,然后破坏它们,这样os.Getwd
就会抛出一个错误供你在测试中捕获。
在执行这些操作时要小心,因为它们可能会破坏你的系统。我建议在轻量级容器或虚拟机中进行测试。
英文:
Looks like that taking a look at the os.Getwd test could give you some example of how you could test your code. Look for the functions TestChdirAndGetwd
and TestProgWideChdir
.
From reading those, it seems that the tests create temporary folders.
So a pragmatic approach would be to create temporary folders, like the tests mentioned above do, then break them so os.Getwd
throws an error for you to catch on your test.
Just be careful doing these operations as they can mess up your system. I'd suggest testing in a lightweight container or a virtual machine.
答案3
得分: 0
我知道有点晚了,但是这是你可以做的方法。
测试 DAL、SystemCalls 或者 package 调用通常很困难。我解决这个问题的方法是将系统函数调用放在一个接口后面,然后模拟这些接口的函数。例如:
type SystemCalls interface {
Getwd() error
}
type SystemCallsImplementation struct{
}
func (SystemCallsImplementation) Getwd() error{
return Os.Getwd()
}
func MyFunc(sysCall SystemCalls) error{
sysCall.Getwd()
}
通过这种方式,你将接口注入到函数中,接口包含系统调用。现在你可以轻松地为测试创建一个模拟实现。
例如:
type MockSystemCallsImplementation struct{
err error
}
func (MockSystemCallsImplementation) Getwd() error{
return err //this can be set to nil or some value in your test function
}
希望这回答了你的问题。
英文:
I know this is a bit late but, here is how you can do it.
Testing DAL or SystemCalls or package calls is usually difficult. My approach to solve this problem is to push your system function calls behind an interface and then mock the functions of those interface. For example.
type SystemCalls interface {
Getwd() error
}
type SystemCallsImplementation struct{
}
func (SystemCallsImplementation) Getwd() error{
return Os.Getwd()
}
func MyFunc(sysCall SystemCalls) error{
sysCall.Getwd()
}
With this you inject your interface that has the system calls to your function. Now you can easily create a mock implementation of your interface for testing.
like
type MockSystemCallsImplementation struct{
err error
}
func (MockSystemCallsImplementation) Getwd() error{
return err //this can be set to nil or some value in your test function
}
Hope this answers your question.
答案4
得分: 0
这是Go编译器的限制,Google开发人员不希望允许任何钩子或猴子补丁。如果单元测试对你很重要,那么你必须选择一种源代码污染的方法。以下是所有这些方法:
- 你不能直接使用全局包。
- 你必须创建一个隔离版本的方法并对其进行测试。
- 生产版本的方法包括隔离版本的方法和全局包。
但是,如果可能的话,最好的解决方案是完全忽略Go语言。
英文:
This is the limitation of go compiler, google developers don't want to allow any hooks or monkey patching. If unit tests are important for you - than you have to select a method of source code poisoning. All these methods are the following:
- You can't use global packages directly.
- You have to create isolated version of method and test it.
- Production version of method includes isolated version of method and global package.
But the best solution is to ignore go language completely (if possible).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论