请考虑以下示例代码:
@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或者扩展它的访问修饰符,因为这样可以对我的字段进行不必要的更改。
答案 0 :(得分:1)
如果您的测试与您的课程位于同一个软件包中,那么您可以直接调用initSomeField
,因为它的软件包是私有的。您可以在每个单独的测试方法中执行此操作,也可以在@Before
方法中执行此操作,前提是它在initMocks
之后运行。