Ich muss einen Test schreiben PartitionMapperTest
für meine Java-Klasse PartitionMapper
. Diese Klasse hat private Felder mit @Inject
Annotationen, aber sie hat nur einen No-Param-Konstruktor.Injizieren private Felder mit @Inject während des Tests?
Für den Test möchte ich einen partitionMapper
vor jedem Test erstellen und Werte in seine privaten Felder injizieren. Dann testet der Tester die Methode des Zuordners mapPartitions
und gibt Werte an. Ich weiß jedoch nicht, wie man diese Werte in partitionMapper
injiziert.
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 ...
}
}
// ...
}
Ich habe tatsächlich ein echtes PartitionMapperTest
auf Mockito und PowerMock Basis zu implementieren, die auf meinem GitHub zu sehen sind. Das Problem ist, dass es so viele Annahmen gibt, dass es zu sehr schlechtem Code für das Benutzerverständnis führt. Ich suche nach einer anderen Lösung für das Refactoring.
Sie Antwort ist eine gute Idee. Ich werde es wahrscheinlich wählen. Aber ich bin gespannt, wie CDI die Werte in private Felder einbringt. Ich meine, es gibt keine Setter, wie schaffen sie das? Wenn ich den gleichen Mechanismus anwende, kann ich das auch erreichen? (Injizieren Sie sie selbst) –
Ich möchte nur einen Konstruktor ohne Argumente haben, weil ich nicht möchte, dass irgendjemand diese interne Klasse in der API instanziiert. Aber sie können es immer noch tatsächlich tun:/ –
Feldinjektionen erfordern Reflektion, soweit ich weiß. Ich nehme an, dass es so gemacht wird: 'Field field = Beispiel.class.getDeclaredField (" fieldName "); field.setAccessible (true); field.set (Instanz, Wert); '. Wenn Sie erzwingen möchten, dass Ihre Klasse nur intern verwendet wird, können Sie Ihr Konstruktorpaket als privat festlegen. Das ist keine 100% ige Lösung, aber besser als nichts. Wenn Sie dies tun, stellen Sie sicher, dass Ihr Test im selben Paket ist ...;) –