如何只模拟接口的一种方法
How to mock only one method of an interface
我正在努力理解 Go 中的模拟(正在寻找与 Mockito.spy 等同于 Go 中的 java 的相关内容)。
假设我在 Go 中有一个接口,有 5 个方法。但是我要测试的这段代码只引用了两种方法。现在我如何在不实现所有方法的情况下模拟这种依赖关系,即我在源代码中的实际实现实现了接口的 5 种方法,但是有没有办法避免在测试文件中实现 5 种方法的虚拟接口实现。以下是我目前的做法,实现 5 个方法是可以管理的,但是如果接口有 20 个方法,模拟实现测试文件中的所有方法会变得乏味。
示例:
handler.go中的源代码:
type Client struct {}
type ClientStore interface {
func(c *Client) methodOne() error {// some implementation}
func(c *Client) methodTwo() error {// some implementation}
func(c *Client) methodThree() error {// some implementation}
func(c *Client) methodFour() error {// some implementation}
func(c *Client) methodFive() error {// some implementation}
}
api.go中的源代码:
func processFeed(c Client) error {
err := c.methodOne()
if(err != null) {
return err
}
err1 := c.methodTwo()
if(err1 != null) {
return err1
}
}
测试class代码:
import "testify/mock"
func TestFeed(t *testing.T){
mockClient := &MockClient{}
err := processFeed(mockClient)
assert.NotNil(t , err)
}
type MockClient struct {
mock.Mock
}
func(c *MockClient ) methodOne() error {fmt.Printf("methodOne");nil}
func(c *MockClient ) methodTwo() error {return errors.New("mocked error")}
func(c *MockClient ) methodThree() error {fmt.Printf("methodThree");nil}
func(c *MockClient ) methodFour() error {fmt.Printf("methodFour");nil}
func(c *MockClient ) methodFive() error {fmt.Printf("methodFive");nil}
问题:
有没有办法只模拟我在上述情况下只需要 methodOne() 和 methodTwo() 方法而不用担心测试中的剩余方法?如果有其他选择,您能否提出建议?谢谢
首先,如果您的接口有 5 个方法,而您只使用一个方法,那么您的接口太大了。使用更小的界面。
type BigInterface interface {
Thing1()
Thing2()
ThingN()
}
type SmallInterface interface {
Thing1()
}
func MyFunc(i SmallInterface) { ... }
另一种选择是通过嵌入完整接口来创建完整接口的完整实现。如果您尝试访问其他方法之一,这将引起恐慌,但如果您小心的话,它将用于测试。 (但请不要在生产代码中这样做!)
type BigInterface interface {
Thing1()
Thing2()
ThingN()
}
type myImplementation struct {
BigInterface
}
func (i *myImplementation) Thing1() { ... }
现在 myImplementation
通过包含 BigInterface
的嵌入式实例满足 BigInterface
接口。如果您从未将该嵌入式实例设置为任何内容,那么调用这些方法将会出现混乱,但您仍然可以定义 Thing1
来执行您想要的测试。
我正在努力理解 Go 中的模拟(正在寻找与 Mockito.spy 等同于 Go 中的 java 的相关内容)。
假设我在 Go 中有一个接口,有 5 个方法。但是我要测试的这段代码只引用了两种方法。现在我如何在不实现所有方法的情况下模拟这种依赖关系,即我在源代码中的实际实现实现了接口的 5 种方法,但是有没有办法避免在测试文件中实现 5 种方法的虚拟接口实现。以下是我目前的做法,实现 5 个方法是可以管理的,但是如果接口有 20 个方法,模拟实现测试文件中的所有方法会变得乏味。
示例:
handler.go中的源代码:
type Client struct {}
type ClientStore interface {
func(c *Client) methodOne() error {// some implementation}
func(c *Client) methodTwo() error {// some implementation}
func(c *Client) methodThree() error {// some implementation}
func(c *Client) methodFour() error {// some implementation}
func(c *Client) methodFive() error {// some implementation}
}
api.go中的源代码:
func processFeed(c Client) error {
err := c.methodOne()
if(err != null) {
return err
}
err1 := c.methodTwo()
if(err1 != null) {
return err1
}
}
测试class代码:
import "testify/mock"
func TestFeed(t *testing.T){
mockClient := &MockClient{}
err := processFeed(mockClient)
assert.NotNil(t , err)
}
type MockClient struct {
mock.Mock
}
func(c *MockClient ) methodOne() error {fmt.Printf("methodOne");nil}
func(c *MockClient ) methodTwo() error {return errors.New("mocked error")}
func(c *MockClient ) methodThree() error {fmt.Printf("methodThree");nil}
func(c *MockClient ) methodFour() error {fmt.Printf("methodFour");nil}
func(c *MockClient ) methodFive() error {fmt.Printf("methodFive");nil}
问题:
有没有办法只模拟我在上述情况下只需要 methodOne() 和 methodTwo() 方法而不用担心测试中的剩余方法?如果有其他选择,您能否提出建议?谢谢
首先,如果您的接口有 5 个方法,而您只使用一个方法,那么您的接口太大了。使用更小的界面。
type BigInterface interface {
Thing1()
Thing2()
ThingN()
}
type SmallInterface interface {
Thing1()
}
func MyFunc(i SmallInterface) { ... }
另一种选择是通过嵌入完整接口来创建完整接口的完整实现。如果您尝试访问其他方法之一,这将引起恐慌,但如果您小心的话,它将用于测试。 (但请不要在生产代码中这样做!)
type BigInterface interface {
Thing1()
Thing2()
ThingN()
}
type myImplementation struct {
BigInterface
}
func (i *myImplementation) Thing1() { ... }
现在 myImplementation
通过包含 BigInterface
的嵌入式实例满足 BigInterface
接口。如果您从未将该嵌入式实例设置为任何内容,那么调用这些方法将会出现混乱,但您仍然可以定义 Thing1
来执行您想要的测试。