在golang中测试第三方软件包

时间:2015-01-29 07:43:24

标签: facebook testing go mocking

我是golang的新手,并尝试使用https://github.com/huandu/facebook的facebook软件包编写一个简单的学习应用。

我能够获得包并连接到Facebook并点击facebook API。这很棒,但测试是我关注的问题。

起初我只是调用方法并在其中创建一个facebook对象。然后经过一些研究我尝试传递facebook方法,我想嘲笑。意识到我需要多种方法,我确信传递接口是正确的方法。

所以我尝试创建包将实现的接口。

type IFbApp interface {
    ExchangeToken(string) (string, int, error)
    Session(string) IFbSession
}

type MyFbApp struct{}

func (myFbApp *MyFbApp) ExchangeToken(token string) (string, int, error) {
    return myFbApp.ExchangeToken(token)
}

func (myFbApp *MyFbApp) Session(token string) IFbSession {
    return myFbApp.Session(token)
}

type IFbSession interface {
    User() (string, error)
    Get(string, map[string]interface{}) (map[string]interface{}, error)
}

type MyFbSession struct{}
func (myFbSession *MyFbSession) User() (string, error) {
    return myFbSession.User()
}

func (myFbSession *MyFbSession) Get(path string, params map[string]string) (map[string]string, error) {
    return myFbSession.Get(path, params)
}

func SomeMethod() {
    Facebook(fb.New("appId", "appSecret")); // fb calls package
}

func Facebook(fbI IFbApp) {
    fbI.ExchangeToken("sometokenhere");
}

由于收到错误

,我无法编译此代码
cannot use facebook.New("appId", "appSecret") (type *facebook.App) as type IFbApp in argument to Facebook:
    *facebook.App does not implement IFbApp (wrong type for Session method)
        have Session(string) *facebook.Session
        want Session(string) IFbSession

将IFbSession切换为* facebook.Session会使其编译当然,但我还需要从Session结构中模拟方法。

我的计划是创建模拟结构,在我的test.go文件中实现我的接口并将其传递给测试中的方法。这是正确的方法吗?

我希望尽可能保持纯粹的golang并远离嘲弄框架。

感谢。

1 个答案:

答案 0 :(得分:1)

您可以为fb.App实现一个包装器并覆盖Session方法以返回IFbSession而不是Facebook.Session。

package main

import fb "github.com/huandu/facebook"

type IFbApp interface {
    ExchangeToken(string) (string, int, error)
    Session(string) IFbSession
}

type MockFbApp struct {
    IFbApp
}

func (myFbApp *MockFbApp) ExchangeToken(token string) (string, int, error) {
    return "exchangetoken", 1, nil
}

func (myFbApp *MockFbApp) Session(token string) IFbSession {
    return &MyFbSession{}
}

type IFbSession interface {
    User() (string, error)
    Get(string, fb.Params) (fb.Result, error)
}

type MyFbSession struct {
    IFbSession
}

func (myFbSession *MyFbSession) User() (string, error) {
    return "userid", nil
}

func (myFbSession *MyFbSession) Get(path string, params fb.Params) (fb.Result, error) {
    return fb.Result{}, nil
}

type RealApp struct {
    *fb.App
}

func (myFbApp *RealApp) Session(token string) IFbSession {
    return myFbApp.App.Session(token)
}

func SomeMethod() {
    Facebook(&MockFbApp{})
    Facebook(&RealApp{fb.New("appId", "appSecret")})
}

func Facebook(fbI IFbApp) {
    fbI.ExchangeToken("sometokenhere")
    fbI.Session("session")
}

func main() {
    SomeMethod()
}