For example, I want to create a user API with 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 an unit test for the user creation API, but I don't want real interaction with the database or mocking. Since the userUseCase requires a repository, it means we'll create a mock userRepository for the SaveUserToDB function.
Is it the right way to use a method like this?
mockRepo.On("SaveUserToDB", mock.Anything, mock.AnythingOfType("*repository.User")).Return(nil)
Dependency injection requires the dependencies to actually be injected. Bootstrap
is creating its dependencies, so it can be argued this isn't dependency injection. If you use Bootstrap
in your test, 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'd 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 dependency, so you should apply this to userProducer
, userUseCase
, etc.