You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
If I have a struct being injected as part of a group, and that struct contains an interface type with decorations, then the decorations for the interface type are ignored for the group constructor.
For example, suppose we have an interface Animal that has a production implementation of ProdBear, and a unit test decoration that returns MockBunny. When groups are not utilized, my app always populates bunny, since it applies the bunny decorator. However, when I create a Zoo with a group of exhibits, then bear is populated for the Zoo exhibits -- everywhere else bunny is populated.
To Reproduce
package main_test
import (
"testing"
"github.com/stretchr/testify/assert"
"go.uber.org/fx"
"go.uber.org/fx/fxtest"
)
type Animal interface {
Name() string
}
type ProdBear struct {
}
var _ Animal = (*ProdBear)(nil)
func NewProdBear() *ProdBear {
return &ProdBear{}
}
func (p *ProdBear) Name() string {
return "bear"
}
type MockBunny struct {
}
var _ Animal = (*MockBunny)(nil)
func (r *MockBunny) Name() string {
return "bunny"
}
func NewMockBunny() *MockBunny {
return &MockBunny{}
}
type Exhibit struct {
Animal Animal
}
func NewExhibit(a Animal) *Exhibit {
return &Exhibit{Animal: a}
}
type ZooParams struct {
fx.In
Exhibits []*Exhibit `group:"exhibits"`
}
type Zoo struct {
Exhibits []*Exhibit
}
func NewZoo(p ZooParams) *Zoo {
return &Zoo{Exhibits: p.Exhibits}
}
type Trainer struct {
Animal Animal
}
func NewTrainer(a Animal) *Trainer {
return &Trainer{Animal: a}
}
func TestFxApp(t *testing.T) {
var env struct {
fx.In
Animal Animal
Trainer *Trainer
Zoo *Zoo
}
app := fxtest.New(t,
fx.Provide(
fx.Annotate(NewProdBear, fx.As(new(Animal))),
),
fx.Decorate(
fx.Annotate(NewMockBunny, fx.As(new(Animal))),
),
fx.Provide(
// Using `group` here results in NewExhibit() being passed a bear instead of a bunny.
fx.Annotate(NewExhibit, fx.ResultTags(`group:"exhibits"`)),
),
fx.Provide(NewTrainer),
fx.Provide(NewZoo),
fx.Populate(&env),
)
defer app.RequireStart().RequireStop()
assert.Equal(t, "bunny", env.Animal.Name())
assert.Equal(t, "bunny", env.Trainer.Animal.Name())
// This fails! Zoo contains a group of exhibits, and the NewExhibit()
// constructor is only given the prod value, not the decorated value.
// expected: "bunny"
// actual : "bear"
assert.Equal(t, "bunny", env.Zoo.Exhibits[0].Animal.Name())
}
Expected behavior
I would expect the above unit test to pass.
Additional context
Tested with fx v1.17.1 and dig v1.14.1
The text was updated successfully, but these errors were encountered:
Describe the bug
If I have a struct being injected as part of a group, and that struct contains an interface type with decorations, then the decorations for the interface type are ignored for the group constructor.
For example, suppose we have an interface
Animal
that has a production implementation ofProdBear
, and a unit test decoration that returnsMockBunny
. When groups are not utilized, my app always populatesbunny
, since it applies the bunny decorator. However, when I create aZoo
with a group ofexhibits
, thenbear
is populated for the Zoo exhibits -- everywhere elsebunny
is populated.To Reproduce
Expected behavior
I would expect the above unit test to pass.
Additional context
Tested with fx
v1.17.1
and digv1.14.1
The text was updated successfully, but these errors were encountered: