Search code examples
spring-bootmockitocxfjunit5

SpringBoot + junit5 + mockito + cxf Caused by: java.lang.IllegalArgumentException: not a proxy instance


My configuration excerpt

<...>
    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        SpringBus springBus = new SpringBus();
        LoggingInInterceptor ipt = new LoggingInInterceptor();
        LoggingOutInterceptor opt = new LoggingOutInterceptor();
        ipt.setPrettyLogging(true);
        opt.setPrettyLogging(true);
        springBus.getInInterceptors().add(ipt);
        springBus.getOutInterceptors().add(opt);
        return springBus;
    }

    @Bean
    public MyService getMyServiceProxy() {
        JaxWsProxyFactoryBean jaxWsProxyFactoryBean =
                new JaxWsProxyFactoryBean();
        jaxWsProxyFactoryBean.setAddress(MyServiceAddress + ":" +
                MyServicePort + MyServiceAddressPath);
        jaxWsProxyFactoryBean.setServiceClass(MyService.class);
        jaxWsProxyFactoryBean.setBus(springBus());
        return jaxWsProxyFactoryBean.create(MyService.class);
    }

    @Bean
    public Client myServiceClentProxy() {
        return ClientProxy.getClient(getMyServiceProxy());
    }

    @Bean
    public HTTPConduit myServiceAgentConduit() {
        HTTPConduit httpConduit =
                (HTTPConduit) myServiceClentProxy().getConduit();
        httpConduit.setAuthorization(basicAuthorization());
        return httpConduit;
    }

    @Bean
    public AuthorizationPolicy basicAuthorization() {
        AuthorizationPolicy authorizationPolicy =
                new AuthorizationPolicy();
        authorizationPolicy.setUserName(myServiceUser);
        authorizationPolicy.setPassword(myServicePassword);
        authorizationPolicy.setAuthorizationType("Basic");

        return authorizationPolicy;
    }
<...>

when I try to run my app normally everything just works, but when I try to run a test it throws an error failing on a phase where configuration is happening.

Caused by: java.lang.IllegalArgumentException: not a proxy instance

full error:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myServiceClientProxy' defined in class path resource [MyServiceConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.cxf.endpoint.Client]: Factory method 'myServiceClientProxy' threw exception; nested exception is java.lang.IllegalArgumentException: not a proxy instance

How to solve this issue? What I'm missing do I need any other library besides mockito and Junit?

Update No. 1

test case is not even related to cxf itself

@ExtendWith(SpringExtension.class)
@ExtendWith(MockitoExtension.class)
@ContextConfiguration(classes = {MyServiceController.class})
@SpringBootTest
@Import(MyServiceApplication.class)
public class ControllerTest {
@Autowired
private MyServiceController myServiceController;

@MockBean
private MyService myService;

@Test
public void doTest() {
    when(myService.doAction(any(String.class))).thenReturn("empty");
   }
}

Update No.2 regarding the class level annotations

@ExtendWith(SpringExtension.class)
@ExtendWith(MockitoExtension.class)
@ContextConfiguration(classes = {MyServiceController.class})
@SpringBootTest
@Import(MyServiceApplication.class)

If I remove any of these annotations, I receive a message

org.springframework.beans.factory.BeanCreationException: Error creating bean with name myService

Update no.3 If I remove @MockBean annotation and qualify

@Bean(name = "serviceProxy")
public RepositoryWS getMyServiceProxy() {}

and

@Bean(name = "clientProxy")
public Client myServiceClientProxy() {
    return ClientProxy.getClient(getMyServiceProxy());
}

and

@ExtendWith(SpringExtension.class)
@ExtendWith(MockitoExtension.class)
@ContextConfiguration(classes = {MyServiceController.class})
@SpringBootTest
@Import(MyServiceApplication.class)
public class ControllerTest {
@Autowired
private MyServiceController myServiceController;

@MockBean
private MyService myService;

@Test
public void doTest() {
    <deleteThisLine>when(myService.doAction(any(String.class))).thenReturn("empty");</deleteThisLine>
   }
}

and if I use @Autowired instead of @MockBean, then again everything works. I'm confused on why mocking is not working.

Update no.4

it seems that error happens here:

package: java.lang.reflect;

class: Proxy.class

    /*
     * Verify that the object is actually a proxy instance.
     */
    if (!isProxyClass(proxy.getClass())) {
        throw new IllegalArgumentException("not a proxy instance");
    }

Solution

  • M. Deinum was right to much cluter was on my ControllerTest class, removing all annotations, but @SpringBootTest, also I had to create configuration solely for test case

    @SpringBootTest(classes = {MyServiceApplicationTest.class})
    public class ControllerTest {
    @Autowired
    private MyServiceController myServiceController;
    
    @MockBean
    private MyService myService;
    
    @Test
    public void doTest() {
        when(myService.doAction(any(String.class))).thenReturn("empty");
       }
    }