This repository has been archived by the owner on Mar 22, 2019. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added the ability to override non-zero values
Previously, if some subtree of an object that was to be populated was not zero/nil, we would terminate the population of that subtree then and there. However this makes the package hard to use for very target dependencies that only occur at the bottom of the dependency tree (e.g: a network client or database layer). With this patch, the injection does move downwards and populate the fields that it can. Furthermore, we can now have constructors populate our structs with default values, that will then be overridden by the injection mechanism if the tag `inject:"override"` is present on the field. This means that we can now use sane defaults when creating our objects that we can inject mocks for during unit tests. ```go // A is our bogus wrapper of the http.Client type A struct { Client *http.Client `inject:"override"` } // NewA returns a fully functional A, with a non-nil http client. func NewA() *A { return &A{ Client: &http.Client{} } } var testClient *http.Client func TestMain(m *testing.M) testClient = NewTestClient() os.Exit(m.Run()) } func TestWithBogusClient(t *testing.T) { a := NewA() inject.Populate(a, testClient) // Here the injector should have overridden the default http client // inside A to use the bogus client. a.Do(...) } ``` The last feature that I was looking for was the traversal of non-nil interfaces. For instance: ```go // I is our bogus interface. It has no functions for the sake of // brevity. type I interface {} // A implements that bogus interface type A struct { Client *http.Client `inject:""` } // Nested contains an I which does not need to be injected. However, // the I (which will be of type A at runtime) needs to be traversed so that // we can inject the right *http.Client. type Nested struct { Iface I } func main() { n := &Nested{ Iface: &A{}, } specialclient := &http.Client{} inject.Populate(n, specialclient) } ``` This is useful in bigger projects when you have many subcomponents that use an *http.Client or sub-interface of that, and need to all have that client mocked during unit tests.
- Loading branch information