Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.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/0/mercurial/2.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 初始化中带有spring引导模拟bean的mockito返回null_Java_Spring Boot_Mockito - Fatal编程技术网

Java 初始化中带有spring引导模拟bean的mockito返回null

Java 初始化中带有spring引导模拟bean的mockito返回null,java,spring-boot,mockito,Java,Spring Boot,Mockito,我在spring boot项目中定义了一些bean,BeanA: @Component public class BeanA { public String getName() { return "A"; } } @Component public class BeanB { @Autowired private BeanA beanA; private String name; @PostConstruc

我在spring boot项目中定义了一些bean,BeanA:

@Component
public class BeanA {
    public String getName() {
        return "A";
    }
}
@Component
public class BeanB {
    @Autowired
    private BeanA beanA;

    private String name;

    @PostConstruct
    public void init() {
        this.name = beanA.getName();
    }

    public String getName() {
        return this.name;
    }

}
BeanB:

@Component
public class BeanA {
    public String getName() {
        return "A";
    }
}
@Component
public class BeanB {
    @Autowired
    private BeanA beanA;

    private String name;

    @PostConstruct
    public void init() {
        this.name = beanA.getName();
    }

    public String getName() {
        return this.name;
    }

}
当我模拟beanA.getName时,它返回null

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { MockitoTestApplication.class })
public class BeanTest {
  @Autowired
  private BeanB beanB;

  @MockBean
  private BeanA beanA;

  @Before
  public void mock() {
    MockitoAnnotations.initMocks(this);
    Mockito.doReturn("mockA").when(beanA).getName();
  }

  @Test
  public void testGetName() {
    System.out.println(beanB.getName()); // return null here
  }
}

我想这里有一些bean加载优先级,根本原因是什么以及如何修复它?

首先,您不需要使用
MockitoAnnotations.initMocks(this)
@MockBean
创建一个mock并将该bean添加到应用程序上下文中(添加一个新的或替换现有的)。从技术上讲,这个mock已经是“mockito支持的”,所以您可以指定对它的期望,等等

现在代码的真正问题是,您试图访问
@Before
方法中的bean,从技术上讲,该方法是在spring发挥其魔力之前调用的,它是JUnit框架的一部分

对于这种情况,spring测试库发明了监听器的概念,监听器绑定到spring应用程序上下文生命周期,而不是单元测试的生命周期

所以从技术上讲,您可以调用
Mockito.doReturn(“mockA”).when(beanA.getName()从监听器中
测试执行监听器#beforeTestMethod
将完成此工作


对于一般性解释,请阅读并通过示例进行更深入的解释

在构建bean之后,您的模拟行为将被重新设置,因此,
getName
已经被调用。重写您的
getName
以执行
return beanA.getName()
,它将返回您想要的内容。还要删除
mockitoannotations。initMocks
Spring Boot测试支持为您处理该问题。如果我在beforeTestMethod中添加Mock逻辑,则when()中的beanA将为空。您可以共享代码吗?您是否使用了正确的合并模式<代码> @ TestExcordListNevices(value = {MyField.class },GyMyMeDe= TestExcordListNo.GyMyMyDe.MeGeGyO.SuffDebug) BTW,以澄清:您从@ M.DeNin得到的评论是完全正确的,因此除了该评论之外,您还应该考虑这个答案。