Java 更改测试中注入的@组件

Java 更改测试中注入的@组件,java,spring,testing,dependency-injection,Java,Spring,Testing,Dependency Injection,我有两节课 @Component public class A { @Autowired B b; } @Component public class B { } 他们是通过Spring的扫描发现的 现在我想测试A,但我需要提供一个不同的impl。对于B,说B锁 如何使Spring找到不同的B,而不是标准的(生产中只有一个) 我的测试带有以下注释: @ContextConfiguration(locations = "classpath:/test-context.xml") 在

我有两节课

@Component
public class A {

  @Autowired
  B b;
}

@Component
public class B {
}
他们是通过Spring的扫描发现的

现在我想测试
A
,但我需要提供一个不同的impl。对于
B
,说
B锁

如何使Spring找到不同的
B
,而不是标准的(生产中只有一个)

我的测试带有以下注释:

@ContextConfiguration(locations = "classpath:/test-context.xml")
在该文件中定义了一些实例(DAO,…),然后在测试类中写入

@Autowired
A testInstance;

你不需要弹簧。这就是依赖注入的全部要点:您可以在单元测试中明确地注入您想要的任何东西。单元测试不应该使用Spring

// constructor injection
B mockB = mock(B.class);
A aUnderTest = new A(mockB);


您可以为测试目的创建单独的xml文件,并注入另一个B对象(BMock),在生产中您可以注入B。因此,有两个单独的配置文件,一个用于生产,另一个用于测试。

根据
Spring文档

Annotation injection is performed before XML injection, thus the latter 
configuration will override the former for properties wired through both approaches.

因此,您可以覆盖测试环境中的
Spring上下文
文件,给出测试实现。但是,如果有多个实现,则无法单独使用
@Autowire
。您还需要使用
@限定符
。所以最好的方法是
mock
测试实现,并使用setter将其注入,这是一个很好的例子,说明了为什么构造函数注入通常优于字段注入。如果您将类重写为在其构造函数中采用
B
,则运行测试不需要任何复杂的东西。@chrylis我实际上最喜欢您的解决方案,我认为它很简单。不使用mockito,我不想模拟,但提供测试实现原理是一样的。创建伪实现,并使用该伪实现构造测试对象。如果你不想使用反射,那么就用构造函数或setter注入代替字段注入;现在,我只是为生产XML提供了一个不同的条目(bean),为测试XML提供了不同的条目。在使用批注时,是否有任何Anologous解决方案?您不需要删除批注。两者都可以使用。当xml文件存在时,注释只是覆盖xml有优先权吗?如果它们是两个不同的类,实现相同的interfaceNot优先级呢。XML注入在注释注入之后执行。因此,如果存在任何带注释的依赖项,它将覆盖。对于第二个问题,您可以使用@Qualifier@Qualifier按名称注入bean
// Field injection, requiring reflection, done by Mockito
@Mock
private B mockB;

@InjectMocks
private A aUnderTest;

@Before
public void initMocks() {
    MockitoAnnotations.initMocks(this);
}
Annotation injection is performed before XML injection, thus the latter 
configuration will override the former for properties wired through both approaches.