Skip to content

Commit 61ba98d

Browse files
authored
Merge pull request #151 from davide954/test/pipeline-unit-coverage
Fix false-positive in EnrichmentPipelineTest by introducing mock Config with DummyModule
2 parents 9212203 + 244b0c8 commit 61ba98d

1 file changed

Lines changed: 58 additions & 9 deletions

File tree

src/test/java/com/digitalpebble/spruce/EnrichmentPipelineTest.java

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55
import org.apache.spark.sql.Row;
66
import org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema;
7+
import org.apache.spark.sql.types.DataTypes;
78
import org.apache.spark.sql.types.StructType;
89
import org.junit.jupiter.params.ParameterizedTest;
910
import org.junit.jupiter.params.provider.CsvSource;
1011

1112
import java.util.Collections;
1213
import java.util.Iterator;
1314
import java.util.List;
15+
import java.util.Map;
1416

1517
import static com.digitalpebble.spruce.CURColumn.*;
1618
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -23,6 +25,56 @@
2325
*/
2426
public class EnrichmentPipelineTest {
2527

28+
/** A lightweight test column used by DummyModule to verify enrichment. */
29+
private static final Column DUMMY_ENRICHED = new Column("dummy_enriched", DataTypes.DoubleType) {};
30+
31+
/**
32+
* Minimal {@link EnrichmentModule} for testing pipeline logic.
33+
* Declares a single output column and sets it to a fixed value during process().
34+
*/
35+
static class DummyModule implements EnrichmentModule {
36+
37+
@Override
38+
public Column[] columnsNeeded() {
39+
return new Column[0];
40+
}
41+
42+
@Override
43+
public Column[] columnsAdded() {
44+
return new Column[]{ DUMMY_ENRICHED };
45+
}
46+
47+
@Override
48+
public Row process(Row row) {
49+
return EnrichmentModule.withUpdatedValue(row, DUMMY_ENRICHED, 42.0);
50+
}
51+
}
52+
53+
/**
54+
* Creates a Config pre-loaded with a single DummyModule.
55+
* This avoids loading the real production modules (which require the full CUR schema)
56+
* and keeps the test focused on the pipeline's Usage-filter logic.
57+
*/
58+
private static Config createMockConfig() {
59+
Config config = new Config();
60+
DummyModule module = new DummyModule();
61+
config.getModules().add(module);
62+
63+
// Also inject matching config entry via reflection so configureModules() works
64+
try {
65+
var configsField = Config.class.getDeclaredField("configs");
66+
configsField.setAccessible(true);
67+
@SuppressWarnings("unchecked")
68+
List<Map<String, Object>> configs =
69+
(List<Map<String, Object>>) configsField.get(config);
70+
configs.add(Collections.emptyMap());
71+
} catch (Exception e) {
72+
throw new RuntimeException("Failed to set up mock config", e);
73+
}
74+
75+
return config;
76+
}
77+
2678
/**
2779
* Verifies the selective enrichment logic based on Line Item Type.
2880
* <p>
@@ -39,21 +91,18 @@ public class EnrichmentPipelineTest {
3991
"Fee, false"
4092
})
4193
public void testPipelineEnrichmentLogic(String lineItemType, boolean expectEnrichment) throws Exception {
42-
Config config = new Config();
94+
Config config = createMockConfig();
4395
EnrichmentPipeline pipeline = new EnrichmentPipeline(config);
4496

45-
// TODO: Validate that modules are loaded (Option 1 - Mocking).
46-
// Currently, new Config() returns an empty list in unit tests.
47-
// We will implement a Mock Config in a separate PR to handle this without
48-
// requiring the full production schema.
49-
// assertFalse(config.getModules().isEmpty(), "Config should have at least one enrichment module");
97+
List<EnrichmentModule> modules = config.getModules();
98+
assertFalse(modules.isEmpty(), "Config should have at least one enrichment module for this test");
5099

51-
// Minimal schema: use ONLY existing constants in CURColumn.
100+
// Minimal schema: base CUR columns + columns added by the DummyModule
52101
StructType schema = new StructType()
53102
.add(PRODUCT_REGION_CODE.getLabel(), PRODUCT_REGION_CODE.getType(), true)
54103
.add(LINE_ITEM_TYPE.getLabel(), LINE_ITEM_TYPE.getType(), true);
55104

56-
for (EnrichmentModule module : config.getModules()) {
105+
for (EnrichmentModule module : modules) {
57106
for (Column c : module.columnsAdded()) {
58107
schema = schema.add(c.getLabel(), c.getType(), true);
59108
}
@@ -75,7 +124,7 @@ public void testPipelineEnrichmentLogic(String lineItemType, boolean expectEnric
75124
assertEquals("us-east-1", PRODUCT_REGION_CODE.getString(processedRow));
76125

77126
// Verify enrichment logic
78-
for (EnrichmentModule module : config.getModules()) {
127+
for (EnrichmentModule module : modules) {
79128
for (Column c : module.columnsAdded()) {
80129
int fieldIndex = processedRow.fieldIndex(c.getLabel());
81130
if (expectEnrichment) {

0 commit comments

Comments
 (0)