使用@PostConstruct方法对EJB进行单元测试

时间:2014-01-24 19:28:01

标签: unit-testing java-ee mockito

请考虑以下示例代码:

@Stateless
public class MyBean {

  private SomeHelper helper;

  private long someField;

  @PostConstruct
  void init() {
    helper = new SomeHelper();

    someField = initSomeField();
  }

  long initSomeField() {
    // perform initialization
  }

  public void methodToTest() {
    helper.someMethod();
    long tmp = 3 + someField;
  }

}

这是测试模板,我总是使用

public class MyBeanTest {

  @Spy
  @InjectMocks
  private MyBean testSubject;

  @Mock
  private SomeHelper mockedHelper;

  @Before
  public void before() {
    MockitoAnnotations.initMocks(this);

    doReturn(1L).when(testSubject).initSomeField();
  }

  @Test
  public void test() {
    testSubject.methodToTest();
    // assertions
  }

}

测试methodToTest的问题是需要初始化字段someField。但初始化是在@PostConstruct方法中完成的。在调用testSubject.methodToTest()之前,我无法运行此方法,因为它会重新初始化helper。另外,我不想手动设置所有的模拟。而且我不想使用反射来设置someField,因为这会使MyBeanTest容易受到MyBean重构。任何人都可以提议,也许更好的设计可以避免这样的情况吗?

一些注意事项:

initSomeField中的逻辑可能非常繁重(包括对数据库的调用),因此我只想在@PostConstruct方法中初始化它一次。

我不想为这个字段创建一个setter或者扩展它的访问修饰符,因为这样可以对我的字段进行不必要的更改。

1 个答案:

答案 0 :(得分:1)

如果您的测试与您的课程位于同一个软件包中,那么您可以直接调用initSomeField,因为它的软件包是私有的。您可以在每个单独的测试方法中执行此操作,也可以在@Before方法中执行此操作,前提是它在initMocks之后运行。