i'm working on legacy project (jee 5, jboss 4.2.3) and i need to write integration tests for this app. I was able to integrate arquillian remote module and run simple tests. But now i would like to mock some services in my ejb using mockito.
Example :
some ejb
@Local
public interface DummyService {
String welcomMessage();
}
@Stateless
@LocalBinding(jndiBinding = "ejb/DummyServiceBean/local")
public class DummyServiceBean implements DummyService {
@EJB(mappedName = "ejb/DummyServiceBean2/local")
private DummyService2 service;
@Override
public String welcomMessage() {
return "world!!!!" + " " + service.getSomething();
}
}
@Local
public interface DummyService2 {
String getSomething();
}
@Stateless
@LocalBinding(jndiBinding = "ejb/DummyServiceBean2/local")
public class DummyServiceBean2 implements DummyService2 {
@Override
public String getSomething() {
return "sth";
}
}
test class
@RunWith(Arquillian.class)
public class DummyServiceTest {
@EJB(mappedName = "ejb/DummyServiceBean/local")
private DummyService service;
@Mock
private DummyService2 service2;
@Deployment
public static Archive<?> createDeployment() {
final JavaArchive javaArchive = ShrinkWrap.create(JavaArchive.class, "test.jar")
.addClasses(DummyService.class, DummyServiceBean.class,
DummyService2.class, DummyServiceBean2.class,
DummyServiceTest.class, InjectMocks.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
return ShrinkWrap.create(EnterpriseArchive.class, "test.ear")
.setApplicationXML(new File("application.xml"))
.addAsLibraries( // add maven resolve artifacts to the deployment
DependencyResolvers.use(MavenDependencyResolver.class)
.loadMetadataFromPom("pom.xml")
.artifact("org.mockito:mockito-all:1.9.5")
.resolveAs(GenericArchive.class))
.addAsModule(javaArchive);
}
@Before
public void setupMock() {
when(service2.getSomething()).thenReturn("qwerty");
}
@Test
public void should_assert_a_behaviour() {
System.out.println("Hello " + service.welcomMessage());
}
}
I can do this by not adding DummyServiceBean2.class into archive and by creating in test directory something like :
@Stateless
@LocalBinding(jndiBinding = "ejb/DummyServiceBean2/local")
public class MockDummyServiceBean2 implements DummyService2 {
@Override
public String getSomething() {
return "mock sth";
}
}
but this is bad practice. I got the idea to swap during runtime DummyServiceBean2 proxy reference using reflection in DummyServiceBean class for a new one with InvocationHandler which use mock inside his invoke method but it ended up on an exception
IllegalArgumentException: Can not set com.example.DummyService2 field com.example.DummyServiceBean.service to com.sun.proxy.$Proxy71
Any ideas how can i swap/replace DummyServiceBean2 proxy for new one or how can i replace invocation handler in existing one ?