|
| 1 | +package inject |
| 2 | + |
| 3 | +import "testing" |
| 4 | + |
| 5 | +// 测试深度注入的各种场景 |
| 6 | +func TestDeepInjectAdvanced(t *testing.T) { |
| 7 | + // 场景1: 多层嵌套的手动注入实例 |
| 8 | + type Level3 struct { |
| 9 | + Value string |
| 10 | + } |
| 11 | + |
| 12 | + type Level2 struct { |
| 13 | + L3 *Level3 `inject:""` |
| 14 | + } |
| 15 | + |
| 16 | + type Level1 struct { |
| 17 | + L2 *Level2 `inject:""` |
| 18 | + } |
| 19 | + |
| 20 | + type Root struct { |
| 21 | + L1 *Level1 `inject:""` |
| 22 | + } |
| 23 | + |
| 24 | + var g Graph |
| 25 | + |
| 26 | + // 手动创建嵌套结构 |
| 27 | + root := &Root{ |
| 28 | + L1: &Level1{ |
| 29 | + L2: &Level2{ |
| 30 | + L3: &Level3{Value: "manually created"}, |
| 31 | + }, |
| 32 | + }, |
| 33 | + } |
| 34 | + |
| 35 | + // 提供根对象 |
| 36 | + if err := g.Provide(&Object{Value: root}); err != nil { |
| 37 | + t.Fatal("failed to provide root:", err) |
| 38 | + } |
| 39 | + |
| 40 | + // 执行深度注入 |
| 41 | + if err := g.Populate(); err != nil { |
| 42 | + t.Fatal("failed to populate:", err) |
| 43 | + } |
| 44 | + |
| 45 | + // 验证深度注入是否成功 |
| 46 | + if root.L1 == nil { |
| 47 | + t.Fatal("root.L1 should not be nil") |
| 48 | + } |
| 49 | + if root.L1.L2 == nil { |
| 50 | + t.Fatal("root.L1.L2 should not be nil") |
| 51 | + } |
| 52 | + if root.L1.L2.L3 == nil { |
| 53 | + t.Fatal("root.L1.L2.L3 should not be nil") |
| 54 | + } |
| 55 | + if root.L1.L2.L3.Value != "manually created" { |
| 56 | + t.Fatal("deep injected value should be preserved") |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | +func TestDeepInjectWithMixedProvision(t *testing.T) { |
| 61 | + // 场景2: 混合手动创建和依赖注入提供的实例 |
| 62 | + type ServiceA struct { |
| 63 | + Name string |
| 64 | + } |
| 65 | + |
| 66 | + type ServiceB struct { |
| 67 | + A *ServiceA `inject:""` |
| 68 | + } |
| 69 | + |
| 70 | + type ServiceC struct { |
| 71 | + B *ServiceB `inject:""` |
| 72 | + } |
| 73 | + |
| 74 | + var g Graph |
| 75 | + |
| 76 | + // 手动提供ServiceA |
| 77 | + serviceA := &ServiceA{Name: "ServiceA"} |
| 78 | + if err := g.Provide(&Object{Value: serviceA}); err != nil { |
| 79 | + t.Fatal("failed to provide serviceA:", err) |
| 80 | + } |
| 81 | + |
| 82 | + // 手动创建包含部分依赖的ServiceC |
| 83 | + serviceC := &ServiceC{ |
| 84 | + B: &ServiceB{}, // B没有A的依赖 |
| 85 | + } |
| 86 | + |
| 87 | + if err := g.Provide(&Object{Value: serviceC}); err != nil { |
| 88 | + t.Fatal("failed to provide serviceC:", err) |
| 89 | + } |
| 90 | + |
| 91 | + // 执行注入 |
| 92 | + if err := g.Populate(); err != nil { |
| 93 | + t.Fatal("failed to populate:", err) |
| 94 | + } |
| 95 | + |
| 96 | + // 验证混合注入结果 |
| 97 | + if serviceC.B == nil { |
| 98 | + t.Fatal("serviceC.B should not be nil") |
| 99 | + } |
| 100 | + if serviceC.B.A == nil { |
| 101 | + t.Fatal("serviceC.B.A should be injected") |
| 102 | + } |
| 103 | + if serviceC.B.A != serviceA { |
| 104 | + t.Fatal("serviceC.B.A should be the same instance as serviceA") |
| 105 | + } |
| 106 | + if serviceC.B.A.Name != "ServiceA" { |
| 107 | + t.Fatal("injected service should preserve its properties") |
| 108 | + } |
| 109 | +} |
| 110 | + |
| 111 | +func TestDeepInjectCircularDependency(t *testing.T) { |
| 112 | + // 场景3: 测试循环依赖的处理(这应该能正常工作) |
| 113 | + type CircularB struct { |
| 114 | + A interface{} `inject:""` |
| 115 | + } |
| 116 | + |
| 117 | + type CircularA struct { |
| 118 | + B *CircularB `inject:""` |
| 119 | + } |
| 120 | + |
| 121 | + var g Graph |
| 122 | + |
| 123 | + // 手动创建一个带有循环依赖的结构 |
| 124 | + a := &CircularA{} |
| 125 | + b := &CircularB{A: a} |
| 126 | + a.B = b |
| 127 | + |
| 128 | + // 提供到依赖图 |
| 129 | + if err := g.Provide(&Object{Value: a}); err != nil { |
| 130 | + t.Fatal("failed to provide a:", err) |
| 131 | + } |
| 132 | + |
| 133 | + if err := g.Provide(&Object{Value: b}); err != nil { |
| 134 | + t.Fatal("failed to provide b:", err) |
| 135 | + } |
| 136 | + |
| 137 | + // 执行注入 |
| 138 | + if err := g.Populate(); err != nil { |
| 139 | + t.Fatal("failed to populate:", err) |
| 140 | + } |
| 141 | + |
| 142 | + // 验证循环依赖保持完整 |
| 143 | + if a.B != b { |
| 144 | + t.Fatal("circular dependency should be preserved") |
| 145 | + } |
| 146 | + if b.A.(*CircularA) != a { |
| 147 | + t.Fatal("circular dependency should be preserved") |
| 148 | + } |
| 149 | +} |
0 commit comments