go - 测试中的模拟方法

标签 go testing mocking

我有一个要测试的类:

type ApiGateway struct {
    username  string
    password  string
    scsClient *scsClient.APIDocumentation
    auth      Auth
}

type Auth struct {
    token   string
    validTo int32
}

func New(host string, scheme string, username string, password string) *ApiGateway {
    var config = scsClient.TransportConfig{host, "/", []string{scheme}}
    var client = scsClient.NewHTTPClientWithConfig(strfmt.Default, &config)

    return &ApiGateway{username, password, client, Auth{}}
}

func (s *ApiGateway) isTokenValid() bool { ... }

此 isTokenValid 方法从类中的每个其他方法调用,以验证和/或更新 API token 。在测试中我想模拟这个方法,所以它总是返回 true 例如。

我如何实现它?


编辑: 我的代码:

apiGateway.go

type StubAdapter struct {
    ApeGatewayAdapter
}

type ApeGatewayAdapter interface {
    isTokenValid() bool
}

type ApiGateway struct {
    username  string
    password  string
    scsClient *scsClient.APIDocumentation
    auth      Auth
    adapter ApeGatewayAdapter
}

type Auth struct {
    token   string
    validTo int32
}

func New(host string, scheme string, username string, password string, a ApeGatewayAdapter) *ApiGateway {
    var config = scsClient.TransportConfig{host, "/", []string{scheme}}
    var client = scsClient.NewHTTPClientWithConfig(strfmt.Default, &config)

    return &ApiGateway{username, password, client, Auth{}, a}
}

apiGateway_test.go

type MockAdapter struct {
    ApeGatewayAdapter
}

func (m MockAdapter) isTokenValid() bool {
    return true
}

func TestApiGateway_GetDevice(t *testing.T) {
    var scsGateway = New("foo.com", "http", "testuser", "testpwd", MockAdapter{})

    fmt.Println(scsGateway.isTokenValid())
}

我希望测试调用我模拟的方法并返回 true 但它没有。

最佳答案

问题是您在 MockAdapter 而不是 ApeGatewayAdapter 中定义了 isTokenValid()。所以,当你尝试测试时,它会说

scsGateway.isTokenValid undefined (type *ApiGateway has no field or method isTokenValid)

您需要更改结构中的体系结构,因为您已经为适配器创建了一个方法 New()(没关系),但这里重要的事情(而且几乎总是在 Go 中)是返回一个接口(interface)!

isTokenValid() 是为外部类型定义的(在您的 MockAdapter 测试用例中),因此您不能调用它,除非您更改类型的定义或者您将方法的实现从 MockAdapter 更改为 ApeGatewayAdapter

我认为最好的解决方案应该是删除 StubAdapter 并直接使用 ApiGateway 并为此类型定义方法 isTokenValid() .然后,您的测试应该可以移除内部 ApeGatewayAdapter 并仅使用 MockAdapter 来模拟 apigateway 及其方法。

您的代码应如下所示:

gateway.go

package gateway

type ApeGatewayAdapter interface {
    isTokenValid() bool
}

type ApiGateway struct {
    username string
    password string
    auth     Auth
}

type Auth struct {
    token   string
    validTo int32
}

func (a ApiGateway) isTokenValid() bool {
    // TODO add your validations
    return true
}

func New(host string, scheme string, username string, password string) ApeGatewayAdapter {

    return ApiGateway{username, password, Auth{}}
}

gateway_test

package gateway

import (
    "fmt"
    "testing"
)

type MockAdapter struct {
}

func (m MockAdapter) isTokenValid() bool {
    return true
}


func TestApiGateway_GetDevice(t *testing.T) {

    gateway := MockAdapter{}
    if gateway.isTokenValid() != true {
        t.Error("Not true")
    }
}

关于go - 测试中的模拟方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52697285/

相关文章:

go - go1.13如何从go程序生成doc

optimization - 约束单目标优化

perl - 我应该在哪里放置 Perl .t 测试的通用实用函数?

unit-testing - RhinoMocks - stub 返回参数的方法

go - 如何使用gorequest发送二进制数据

go - 从命名管道连续读取

android - 测试 Activity onCreate Exception

testing - 无法使用 Capybara,不确定我哪里出错了 'background' 和 'it' 等不工作

c# - Visual Studio 2012 Fakes - 如何验证调用的方法?

用 Jest 测试 axios 拦截器