Home  >  Article  >  Backend Development  >  How to create unit tests with dependency injection using Golang

How to create unit tests with dependency injection using Golang

PHPz
PHPzforward
2024-02-11 15:42:08405browse

如何使用 Golang 创建单元测试依赖注入

php editor Youzi brings you an article on how to use Golang to create unit test dependency injection. In software development, unit testing is a crucial part, and dependency injection is a commonly used design pattern that can help us perform unit testing better. This article will briefly introduce how to use Golang to implement dependency injection so that we can write testable code more easily. Let’s explore together!

Question content

For example, I want to create a user API Having a dependency injection structure like this

func Bootstrap(config *BootstrapConfig) {
// setup repositories
userRepository := repository.NewUserRepository(config.Log)
// setup producer
userProducer := messaging.NewUserProducer(config.Producer, config.Log)
// setup use cases
userUseCase := usecase.NewUserUseCase(config.DB, config.Log, config.Validate, userRepository, userProducer)
// setup controller
userController := http.NewUserController(userUseCase, config.Log)
routeConfig := route.RouteConfig{
    App:               config.App,
    UserController:    userController,
}
routeConfig.Setup()
}

Then, I want to create a unit test for the user creation API, but I don't want to actually interact or simulate with the database. Since userUseCase requires a repository, this means we will create a mock userRepository for the SaveUserToDB function.

Is this the correct method to use?

mockRepo.On("SaveUserToDB", mock.Anything, mock.AnythingOfType("*repository.User")).Return(nil)

Workaround

Dependency injection requires actually injecting the dependencies. Bootstrap is creating its dependencies, so we can say this is not dependency injection. If you use Bootstrap in your tests, then this is definitely not dependency injection.

So you need to change func Bootstrap(config *BootstrapConfig) to at least func Bootstrap(config *BootstrapConfig, userRepository *repository.User).

Then, in your test, you pass mockRepo to Bootstrap.

func Bootstrap(config *BootstrapConfig, userRepository *repository.User) {
    // setup producer
    userProducer := messaging.NewUserProducer(config.Producer, config.Log)
    // setup use cases
    userUseCase := usecase.NewUserUseCase(config.DB, config.Log, config.Validate, userRepository, userProducer)
    // setup controller
    userController := http.NewUserController(userUseCase, config.Log)
    routeConfig := route.RouteConfig{
        App:               config.App,
        UserController:    userController,
    }
    routeConfig.Setup()
}

func TestFoo(t *testing.T) {
    mockRepo := mocks.NewUserRepository(config.Log)
    Bootstrap(config, mockRepo)
    mockRepo.On("SaveUserToDB", mock.Anything).Return(nil)
    …
}

Bootstrap should not create any dependencies, so you should apply it to userProducer, userUseCase, etc.

The above is the detailed content of How to create unit tests with dependency injection using Golang. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete