Java mockito spy不适用于工厂bean方法

Java mockito spy不适用于工厂bean方法,java,spring-boot,mockito,spring-boot-test,springmockito,Java,Spring Boot,Mockito,Spring Boot Test,Springmockito,我有一个springboot,我正在为它编写单元测试。有一个factoryBean,我在运行时从中获取服务对象。我想测试是否调用了此服务对象上的特定方法。这是应用程序代码 @Component public class AppClient { @Autowired ServiceFactory factory Service secretService @postContruct public void init(){ this.se

我有一个springboot,我正在为它编写单元测试。有一个factoryBean,我在运行时从中获取服务对象。我想测试是否调用了此服务对象上的特定方法。这是应用程序代码

@Component
public class AppClient {

    @Autowired
    ServiceFactory factory

    Service secretService

    @postContruct
    public void init(){
        this.secretService=factory.get("secret");
    }

    public void process(Map<String, Object> param){
        for (String key: param.keySet()){
            if (key.equals("foobar")){
                restService.handle(param.get(key));
            }
        }
    }
}

通过此更改,工厂bean被模拟,但AppClient中的secretService内部为空。也就是说,secretService没有被插入。通过调试器进行测试。

在spring应用程序完全运行之前以及在您的测试类对工厂的模拟进行一些准备之前,执行
PostConstruct
回调。您无法声明Mockito
when().then()
PostConstruct
回调中运行的代码的期望值

我建议您在
AppClient
bean中进行基于构造函数的注入:

@组件
公共类应用客户端{
私人最终服务工厂
@自动连线
公共应用客户端(ServiceFactory工厂){
这个工厂=工厂;
}
...
}
并将其作为一个简单的单元测试进行测试。通过手动创建AppClient实例,注入工厂模拟,执行
init
方法,并验证所需的所有内容:

@测试
void initTest(){
当(factory.get(…)。然后返回(…);
AppClient=新的AppClient(工厂);
client.init();
验证(…)
}

我建议您调试您的测试,并查明
restService.handle
是否真的被调用,以及参数是否真的是您的
MyDummyObject
。然后你就会知道你对Mockito的使用是否真的错了。没错,你错过了。抱歉,我将删除我的评论以避免混淆。@DawoodibnKareem如果你看到这篇文章,我提到了我在Debugger中观察到的内容,但是它是在测试中创建的同一个MyDummyObject上调用的吗?@DawoodibnKareem在同一个对象上调用的(因为equals和hashcode被重写)
@RunWith(SpringRunner.class)
@SpringBootTest
public class AppTest {

  @Autowired
  AppClient appClient;

  @SpyBean
  ServiceFactory factory;

  Service secretService;

  @Before
  public void init(){
    this.secretService=Mockito.spy(factory.get("secret"));
  }

  @Test
  public void testProcess() {
    Object obj = new MyDummyObject();
    Map<String, Object> params = new HashMap<>();
    params.put("foobar", obj);
    appClient.process(params);
    Mockito.verify(secretService).handle(obj);
  }
}
@MockBean
ServiceFactory factory;

@Mock
Service secretService

@Before
public void init(){
  Mockito.when(factory.get(eq("secret"))).thenReturn(secretService);
}