我有以下EJB:
PersonService.java
@Local
public interface PersonService {
long countPersons();
}
PersonServiceImpl.java
@Stateless
public class PersonServiceImpl implements PersonService {
@EJB
private RemotePersonService remotePersonService;
@Override
public long countPersons() {
return remotePersonService.getAllPersons().size();
}
}
RemotePersonService.java
@Local
public interface RemotePersonService {
List<Person> getAllPersons();
}
RemotePersonServiceImpl.Java
@Stateless
public class RemotePersonServiceImpl {
@Override
public List<Person> getAllPersons() {
// Here, I normally call a remote webservice, but this is for the purpose of this question
List<Person> results = new ArrayList<Person>();
results.add(new Person("John"));
return results;
}
}
这是我的测试
AbstractTest.java
public abstract class AbstractTest {
private InitialContext context;
@BeforeClass(alwaysRun = true)
public void setUp() throws Exception {
System.setProperty("java.naming.factory.initial", "org.apache.openejb.client.LocalInitialContextFactory");
Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("/unittest-jndi.properties"));
context = new InitialContext(properties);
context.bind("inject", this);
}
@AfterClass(alwaysRun = true)
public void tearDown() throws Exception {
if (context != null) {
context.close();
}
}
}
PersonServiceTest.java
@LocalClient
public class PersonServiceTest extends AbstractTest {
@EJB
private PersonService personService;
@Test
public void testPersonService() {
long count = personService.countPersons();
Assert.assertEquals(count, 1l);
}
}
现在,我想要做的是使用Mockito通过模拟替换 PersonServiceImpl.java 中的RemotePersonService实现,并且仍然在我的 testPersonService 方法中进行相同的调用。
我试过了:
PersonServiceTest.java
@LocalClient
public class PersonServiceTest extends AbstractTest {
@Mock
private RemotePersonService remotePersonService;
@EJB
@InjectMocks
private PersonService personService;
@BeforeMethod(alwaysRun = true)
public void setUpMocks() {
MockitoAnnotations.initMocks(this);
List<Person> customResults = new ArrayList<Person>();
customResults.add(new Person("Alice"));
customResults.add(new Person("Bob"));
Mockito.when(remotePersonService.getAllPersons()).thenReturn(customResults);
}
@Test
public void testPersonService() {
long count = personService.countPersons();
Assert.assertEquals(count, 2l);
}
}
但这不起作用。 @Mock RemotePersonService未在PersonService中注入,并且仍在使用真正的EJB。
我该如何使用?
答案 0 :(得分:2)
不要在测试中使用注释。有一个构造函数将连接所有依赖项。
@Stateless
public class PersonServiceImpl implements PersonService {
@EJB
private RemotePersonService remotePersonService;
// Let your test instantiate a mock service and wire it into your test instance using this constructor.
public PersonServiceImpl(RemotePersonService rps) {
this.remotePersonService = rps;
}
@Override
public long countPersons() {
return remotePersonService.getAllPersons().size();
}
}
创建模拟并将其传递给它。您的测试可能如下所示:
@LocalClient
public class PersonServiceTest extends AbstractTest {
@Test
public void testPersonService() {
RemotePersonService mockRemotePersonService = Mockito.mock(RemotePersonService.class);
List<Person> customResults = new ArrayList<Person>();
customResults.add(new Person("Alice"));
customResults.add(new Person("Bob"));
Mockito.when(mockRemotePersonService.getAllPersons()).thenReturn(customResults);
PersonService personService = new PersonServiceImpl(mockRemotePersonService);
long count = personService.countPersons();
Assert.assertEquals(count, 2l);
}
}
答案 1 :(得分:0)
我在类上使用 setter,并查找 ejb
private ServicioAsyncMessaging servicioNotificaciones;
我删除了@EJB --> 和 getter
public ServicioAsyncMessaging getServicioNotificaciones() {
if(servicioNotificaciones == null){
servicioNotificaciones = (ServicioAsyncMessaging)Lookup.getEjb(EjbJndiConstantes.EJB_SERVICIO_ASYNC_MSG);
}
return servicioNotificaciones;
}
public void setServicioNotificaciones(ServicioAsyncMessaging servicioNotificaciones) {
this.servicioNotificaciones = servicioNotificaciones;
}
查找es:
public static Object getEjb(String lookupName){
Object t = null;
try {
Context ctx = new InitialContext();
t= ctx.lookup(lookupName);
} catch (NamingException e) {
log.error("getEjb | Error {}",e.getMessage(),e);
}
return t;
}
通过这些更改,mockito --> 在 setter 上注入模拟。