duancuo1234 2017-07-23 08:02
浏览 7
已采纳

我是否应该始终将结构属性定义为可测试性的接口?

As far as I understand the only way to mock structure dependencies in Go is to use interfaces. So my question is: In cases when my struct has methods which perform some actions (when structure is not just a model storing data), should I always define the properties as interfaces in order to properly mock & test it?

Simple example:

type UserService struct {
    userRepository UserRepository
}

func (us *UserService) MaleUsers() []User {
    all := us.userRepository.FindAll()
    maleUsers := []User{}
    for _, u := range all {
        if u.gender == "male" {
            maleUsers = append(maleUsers, u)
        }
    }
    return maleUsers
}

Imagine we have user service which has a dependency: repository. Service has method which gets all users and then filters them by some criteria. By the way filtering logic could go in a separate dependency to avoid filtering in service method (SRP).

Btw. I came from Java world. If this approach of structuring applications is not ideomatic in Go please let me know.

  • 写回答

2条回答 默认 最新

  • dphw5101 2017-07-23 09:06
    关注

    In order to mock the userRepository dependency of your UserService, you are correct in thinking the best approach would be to use an interface.

    Firstly, create your interface:

    type UserRepository interface {
        FindAll() []Users
    }
    

    Then build a mock:

    type MockUserRepository struct{}
    
    func (mock MockUserRepository) FindAll() []Users {
        // here you would manually build a slice of users and return it
        return []Users
    }
    

    Finally, use this mock as as a dependency in your test case:

    func TestMaleUsers(t *testing.T) {
        // compose service using mock
        service := UserService {
            userRepository: MockUserRepository,
        }
    
        // get output of method call
        users := service.MaleUsers()
    
        // perform assertions on output
    }
    

    This way you have created a mock of your interface which can be used in your tests without having to perform any database calls on your repository.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容