我需要为我的Java类PartitionMapperTest
编写一个测试PartitionMapper
。此类具有带有@Inject
注释的私有字段,但它只有一个无参数构造函数。
对于测试,我想在任何测试之前创建partitionMapper
并将值注入其私有字段。然后,测试人员测试映射器的方法mapPartitions
并断言值。但是,我不知道如何将这些值注入partitionMapper
。
PartitionMapper.java
@Named
public class PartitionMapper implements javax.batch.api.partition.PartitionMapper {
@Inject
private JobContext jobContext;
@Inject
@BatchProperty
private String fetchSize;
@Inject
@BatchProperty
private String rowsPerPartition;
// other batch properties ...
@PersistenceUnit(unitName = "h2")
private EntityManagerFactory emf;
@Override
public PartitionPlan mapPartitions() throws Exception {
// ...
}
}
PartitionMapperTest.java
public class PartitionMapperTest {
private PartitionMapper partitionMapper;
@Before
public void setUp() {
// Prepare JobContext, batch properties to inject ...
// Instantiation
partitionMapper = new PartitionMapper();
// TODO How to inject these objects into partitionMapper?
}
@Test
public void testMapPartitions() throws Exception {
PartitionPlan partitionPlan = partitionMapper.mapPartitions();
for (Properties p : partitionPlan.getPartitionProperties()) {
// Assertions here ...
}
}
// ...
}
我确实实现了基于Mockito和PowerMock的真实PartitionMapperTest
,可以在我的GitHub上看到。问题在于有如此多的假设导致用户理解的代码非常差。我正在寻找另一种重构它的解决方案。
答案 0 :(得分:2)
有没有理由只有一个没有args的构造函数?
我建议您使用构造函数注入而不是字段注入。这可以解决你的问题。
例如,而不是:
public class Foo {
@Inject
private Bar bar;
}
这样做:
public class Foo {
private Bar bar;
public Foo(@Inject Bar bar) {
this.bar = bar;
}
}
如果以这种方式定义注入点,则可以使用干净的API,并且可以在非cdi环境中使用您的类(如单元测试)。
有很多关于“构造函数注入VS字段注入”的资源...也在stackoverflow上,例如https://stackoverflow.com/a/19382081/4864870
答案 1 :(得分:1)
使用受保护的字段而不是私有字段可以在单元测试中模拟字段:
@Named
public class PartitionMapper implements javax.batch.api.partition.PartitionMapper {
@Inject
JobContext jobContext;
@Inject
@BatchProperty
String fetchSize;
@Inject
@BatchProperty
String rowsPerPartition;
// other batch properties ...
@PersistenceUnit(unitName = "h2")
EntityManagerFactory emf;
@Override
public PartitionPlan mapPartitions() throws Exception {
// ...
}
}