Java 如何在Junit中使用@InjectMocks和@Autowired注释
我有一个a类,它使用3个不同的类进行自动布线Java 如何在Junit中使用@InjectMocks和@Autowired注释,java,spring,junit,mocking,mockito,Java,Spring,Junit,Mocking,Mockito,我有一个a类,它使用3个不同的类进行自动布线 public class A () { @Autowired private B b; @Autowired private C c; @Autowired private D d; } 在测试它们时,我只希望有两个类(B&C)作为模拟,并将类D自动连接为正常运行,此代码不适用于我: @RunWith(MockitoJUnitRunner.class) public class aTest ()
public class A () {
@Autowired
private B b;
@Autowired
private C c;
@Autowired
private D d;
}
在测试它们时,我只希望有两个类(B&C)作为模拟,并将类D自动连接为正常运行,此代码不适用于我:
@RunWith(MockitoJUnitRunner.class)
public class aTest () {
@InjectMocks
private A a;
@Mock
private B b;
@Mock
private C c;
@Autowired
private D d;
}
甚至可以这样做吗?应该是这样的
@RunWith(SpringJUnit4ClassRunner.class)
public class aTest () {
@Mock
private B b;
@Mock
private C c;
@Autowired
@InjectMocks
private A a;
}
如果你想D
成为Autowired
无需在测试
课程中做任何事情。您的Autowired
A
应该具有正确的D
实例。
另外,我认为您需要使用SpringJUnit4ClassRunner
进行自动布线
,并正确设置contextConfiguration
。
因为您没有使用MockitoJunitRunner
您需要使用
initMocks(java.lang.Object testClass)
我也面临同样的问题,并尝试了萨扬·钱德兰的答案。它在我的例子中不起作用,因为我使用@SpringBootTest注释只加载我所有bean的一个子集。目标不是加载我正在模仿的bean,因为它们有很多其他依赖项和配置 我发现以下解决方案的变体对我有用,在正常情况下也可用
@RunWith(SpringRunner.class)
@SpringBootTest(classes={...classesRequired...})
public class aTest () {
@Mock
private B b;
@Mock
private C c;
@Autowired
@Spy
private D d;
@InjectMocks
private A a;
@Before
public void init(){
MockitoAnnotations.initMocks(this);
}
}
有没有办法继续使用@RunWith(MockitoJUnitRunner.class)来解决这个问题?上面的代码只是更大的测试类的一部分,我不能改变我们运行JUnits的方式是的,你可以,但是你不能在这种情况下使用
Autowired
,您必须手动编写自己的代码来初始化spring上下文加载A
的实例。这种方法在某种情况下不起作用:当A
用@Transactional
注释时(或方法用@Transactional
注释时);请参见,需要注意的是,对象将通过自动关联创建,模拟将由setter注入。我从未想到过这一点,因为我的对象只有一个构造函数,而这些字段没有设置器,所以模拟实例没有被注入(也没有报告它没有注入模拟)。这打破了我所希望的模型(不可变对象),因此,与其他模型一样,我相信InjectMocks可能是个坏主意。一个重要的问题是:如果类的构造函数中有@Autowired,并且试图模拟的字段被设置为final,那么注入将不起作用。这是一个更好的解决方案,因为您可以使用类D,即使它不在类a中@Autowired!