为了账号安全,请及时绑定邮箱和手机立即绑定

如何在测试中将模型与控制器分开?

如何在测试中将模型与控制器分开?

Go
慕森王 2021-08-23 17:51:49
所以我想在测试中将控制器与模型隔离,这样我就可以在出现问题时轻松解决问题。之前,我只是使用模拟数据访问端点,但很难排除故障,因为测试从路由器一直运行到数据存储。所以我想也许我会为每个控制器(和模型)创建两个版本(MockController vs Controller),并根据模式变量的值使用一个。简而言之,这就是我计划实施它的方式。const mode string = "test"// UserModelInterface is the Interface for UserModeltype UserModelInterface interface {    Get() }// UserControllerInterface is the Interface for UserControllertype UserControllerInterface interface {    Login()}// NewUserModel returns a new instance of user modelfunc NewUserModel() UserModelInterface {    if mode == "test" {        return &MockUserModel{}    } else {        return &UserModel{}    }}// NewUserController returns a new instance of user controllerfunc NewUserController(um UserModelInterface) UserControllerInterface {    if mode == "test" {        return &MockUserController{}    } else {        return &UserController{}    }}type (    UserController struct {um UserModelInterface}    UserModel struct {}    // Mocks    MockUserController struct {um UserModelInterface}    MockUserModel struct {})func (uc *UserController) Login() {}func (um *UserModel) Get() {}func (uc *MockUserController) Login() {}func (um *MockUserModel) Get() {}func main() {    um := NewUserModel()    uc := NewUserController(um)}这样我就可以跳过 sql 查询MockUserController.Login(),只验证有效负载并返回有效响应。你觉得这个设计怎么样?你有更好的实现吗?
查看完整描述

2 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

我会让调用 NewUserController() 和 NewUserModel() 的代码决定是创建模拟还是真实实现。如果您一直使用这种依赖注入模式直到顶部,您的代码将变得更清晰,耦合度也会降低。例如,如果用户控制器被服务器使用,它看起来像这样:

真实:

u := NewUserController() s := NewServer(u)

在测试中:

u := NewMockUserController() s := NewServer(u)


查看完整回答
反对 回复 2021-08-23
?
慕沐林林

TA贡献2016条经验 获得超9个赞

我会尝试一个更纤薄的变体,分布在模型和控制器包上,如下所示:


// inside package controllers


type UserModel interface {

    Get() // the methods you need from the user model

}


type User struct {

    UserModel

}


// inside package models


type User struct {

    // here the User Model

}



// inside package main


import ".....controllers"

import ".....models"


func main() {

    c := &controllers.User{&models.User{}}

}


// inside main_test.go

import ".....controllers"


type MockUser struct {


}



func TestX(t *testing.T) {

    c := &controllers.User{&MockUser{}}

}

对于控制器测试,请考虑httptest 包的ResponseRecorder


查看完整回答
反对 回复 2021-08-23
  • 2 回答
  • 0 关注
  • 173 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信