java 使用 Mockito、TestNG 和 OpenEJB 对 EJB 进行单元测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31403973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unit testing an EJB with Mockito, TestNG and OpenEJB
提问by Yotus
I have the following EJB's:
我有以下 EJB:
PersonService.java
人员服务.java
@Local
public interface PersonService {
long countPersons();
}
PersonServiceImpl.java
PersonServiceImpl.java
@Stateless
public class PersonServiceImpl implements PersonService {
@EJB
private RemotePersonService remotePersonService;
@Override
public long countPersons() {
return remotePersonService.getAllPersons().size();
}
}
RemotePersonService.java
远程人员服务.java
@Local
public interface RemotePersonService {
List<Person> getAllPersons();
}
RemotePersonServiceImpl.Java
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;
}
}
And here are my tests
这是我的测试
AbstractTest.java
抽象测试.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
人员服务测试.java
@LocalClient
public class PersonServiceTest extends AbstractTest {
@EJB
private PersonService personService;
@Test
public void testPersonService() {
long count = personService.countPersons();
Assert.assertEquals(count, 1l);
}
}
Now, want I want to do is replace the RemotePersonService implementation in PersonServiceImpl.javaby a mock using Mockito, and still have the same call in my testPersonServicemethod.
现在,我想要做的是用 Mockito 的模拟替换PersonServiceImpl.java 中的 RemotePersonService 实现,并且在我的testPersonService方法中仍然有相同的调用。
I tried that:
我试过了:
PersonServiceTest.java
人员服务测试.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);
}
}
But this doesn't work. The @Mock RemotePersonService is not injected in the PersonService, and the true EJB is still used.
但这不起作用。在PersonService中没有注入@Mock RemotePersonService,仍然使用真正的EJB。
How can I make this work ?
我怎样才能使这项工作?
采纳答案by duffymo
Don't use annotations for your tests. Have a constructor that will wire in all your dependencies.
不要在测试中使用注释。有一个构造函数可以连接所有依赖项。
@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();
}
}
Create mocks and pass them to it. Your test might look like this:
创建模拟并将它们传递给它。您的测试可能如下所示:
@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);
}
}