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!
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)
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!