Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Junit中使用@InjectMocks和@Autowired注释_Java_Spring_Junit_Mocking_Mockito - Fatal编程技术网

Java 如何在Junit中使用@InjectMocks和@Autowired注释

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 ()

我有一个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 () {

    @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!