无法从模拟的组件类调用该函数

时间:2018-04-03 12:36:56

标签: java unit-testing junit mockito

我有一个junit测试方法如下:

@SpringBootTest
public class StoreIdAssignmentServiceTest {

    private static final Logger log = LoggerFactory
            .getLogger(StoreIdAssignmentServiceTest.class);

    @InjectMocks
    private StoreIdAssignmentService storeIdAssignmentService;

    @Mock
    private StoreIdAssignmentFactory storeIdAssignmentFactory;

    @Mock
    private DatabaseService databaseService;
    @Test
    public void rollUpFeed_Single_DealerAndStoreID_NoExisting() {
        List<ScmsaPosTransRollup> scmsaPosTransRollupFeedList = new ArrayList<>();
        ScmsaPosTransRollup posTransRollup = new ScmsaPosTransRollup();
        posTransRollup.setJobLogId(8269726L);
        posTransRollup.setDealerCode("3119255");
        posTransRollup.setStoreId("9842");
        posTransRollup.setTransactionDate(Timestamp
                .valueOf("2018-03-01 13:00:00.00"));
        posTransRollup.setQuantity(4);
        posTransRollup.setRollupType("H");
        scmsaPosTransRollupFeedList.add(posTransRollup);
        Mockito.when(
                databaseService.getUnProcessedRollUpFeedBasedonRollupType("H"))
                .thenReturn(scmsaPosTransRollupFeedList);
        List<PosHourlySt> existingPosHourlyStEntries = new ArrayList<>();
        Mockito.when(databaseService.getDealerCodeFromPosHourly("3119255"))
                .thenReturn(existingPosHourlyStEntries);

        Mockito.when(databaseService.getDealerCodeFromPosHourly("3119255"))
                .thenReturn(existingPosHourlyStEntries);
        storeIdAssignmentService.processHourlyStateFeed();
        assertNotNull(posHourlyStRepository.findAll());
    }
}

我的StoreIdAssignmentService类将是:

@Service
public class StoreIdAssignmentService {

private StoreIdAssignmentFactory storeIdAssignmentFactory;
    private DatabaseService databaseService;

    @Autowired
    public StoreIdAssignmentService(StoreIdAssignmentFactory storeIdAssignmentFactory,
            DatabaseService databaseService) {
        this.storeIdAssignmentFactory = storeIdAssignmentFactory;
        this.databaseService = databaseService;
    }

    public void processHourlyStateFeed() {
    .......................

                calculateStateForPosHourlyStTransaction(posHourlyStToConsider, newPosHourlyStEntries);
                .........
            }

            List<ScmsaPosTransRollup> scmsaPosTransRollupUpdatedFlagList = storeIdAssignmentFactory
                    .createUpdatedRollUpEntries(rollUpFeedByDealerCode);

            saveAndUpdatePosHourlyStAndRollUpEntries(newPosHourlyStEntries, existingPosHourlyStEntries,
                    rollUpFeedByDealerCode, scmsaPosTransRollupUpdatedFlagList);
        }
    }


    private Map<String, List<ScmsaPosTransRollup>> groupDealerCodeRollUpFeedByStoreId(
            List<ScmsaPosTransRollup> rollUpFeedByDealerCode) {

        // Grouping the rollUpFeedByDealerCode by storeID
        return rollUpFeedByDealerCode.stream().collect(Collectors.groupingBy(ScmsaPosTransRollup::getStoreId));

    }

    private void calculateStateForPosHourlyStTransaction(ScmsaPosTransRollup scmsaPosTransRollupToConsider, List<PosHourlySt> newPosHourlyStEntries) {

        List<PosHourlySt> posHourlyStList = newPosHourlyStEntries.stream().filter(
                hourlyState -> (hourlyState.getStartDate().before(scmsaPosTransRollupToConsider.getTransactionDate())))
                .collect(Collectors.toList());

                ..............

            PosHourlySt posHourlySt=storeIdAssignmentFactory.createHourlyStEntryFromRollUp(scmsaPosTransRollupToConsider,
                    Timestamp.valueOf(scmsaPosTransRollupToConsider.getTransactionDate().toLocalDateTime().withHour(0).withMinute(0)),
                    Timestamp.valueOf(scmsaPosTransRollupToConsider.getTransactionDate().toLocalDateTime().withHour(23).withMinute(59)));
            newPosHourlyStEntries.add(posHourlySt);

            ....................

    }
}

和我的工厂课程将是:

@Component
public class StoreIdAssignmentFactory {

    private static final Logger log = LoggerFactory.getLogger(StoreIdAssignmentFactory.class);

    private ModelMapper modelMapper;

    @Autowired
    public StoreIdAssignmentFactory(ModelMapper modelMapper) {
        this.modelMapper = modelMapper;
    }

    public PosHourlySt createHourlyStEntryFromRollUp(ScmsaPosTransRollup scmsaPosTransRollup, Timestamp startDate, Timestamp endDate){
        PosHourlySt posHourlySt = new PosHourlySt();
        posHourlySt.setDealerCode(scmsaPosTransRollup.getDealerCode());
        posHourlySt.setSourceJobLogId(scmsaPosTransRollup.getJobLogId());
        posHourlySt.setStartDate(startDate);
        posHourlySt.setStoreId(scmsaPosTransRollup.getStoreId());
        posHourlySt.setEndDate(endDate);
        posHourlySt.setJobLogId(0L);
        posHourlySt.setSource("ROLLUP");
        log.info("New Rec: {}", posHourlySt.toString());
        return posHourlySt;
    }

    public PosHourlySt createHourlyStEntryFromPosHourlySt(PosHourlySt posHourlyStToSplit, Timestamp endDate){
        PosHourlySt posHourlySt = new PosHourlySt();
        posHourlySt.setDealerCode(posHourlyStToSplit.getDealerCode());
        posHourlySt.setSourceJobLogId(posHourlyStToSplit.getJobLogId());
        posHourlySt.setStartDate(posHourlyStToSplit.getStartDate());
        posHourlySt.setStoreId(posHourlyStToSplit.getStoreId());
        posHourlySt.setEndDate(endDate);
        posHourlySt.setJobLogId(0L);
        posHourlySt.setSource("ROLLUP");
        log.info("SplitupRec: {}", posHourlySt.toString());
        return posHourlySt;
    }


    public List<ScmsaPosTransRollup> createUpdatedRollUpEntries(List<ScmsaPosTransRollup> rollUpFeedByDealerCode) {
        List<ScmsaPosTransRollup> scmsaPosTransRollupUpdatedFlagList = new ArrayList<>();

        for(ScmsaPosTransRollup scmsaPosTransRollupFeed : rollUpFeedByDealerCode) {
            ScmsaPosTransRollup scmsaPosTransRollupUpdateFlag = new ScmsaPosTransRollup();
            modelMapper.map(scmsaPosTransRollupFeed, scmsaPosTransRollupUpdateFlag);
            scmsaPosTransRollupUpdateFlag.setProcessedFlag("Y");

            scmsaPosTransRollupUpdatedFlagList.add(scmsaPosTransRollupUpdateFlag);
        }
        return scmsaPosTransRollupUpdatedFlagList;
    }
}

StoreIdAssignmentService类包含调用Factory类中某些方法的方法“calculateStateForPosHourlyStTransaction”。当我调试为junit测试用例时,我无法调用该工厂类方法。我在这做错了什么。任何人都可以建议我。

1 个答案:

答案 0 :(得分:0)

你在嘲笑工厂:

@Mock
private StoreIdAssignmentFactory storeIdAssignmentFactory;

所以你无法调查工厂内的方法createHourlyStEntryFromRollUp,因为整个工厂都被嘲笑了:

storeIdAssignmentFactory.createHourlyStEntryFromRollUp

如果您尝试调试createHourlyStEntryFromRollUpStoreIdAssignmentFactory@Component(或@Service),我建议您创建一个StoreIdAssignmentFactoryTest类测试,使用其上的@Autowired@MockBean他的依赖关系。

示例:

@SpringBootTest
public class StoreIdAssignmentFactoryTest {

    @Autowired
    StoreIdAssignmentFactory factory;

    @Test
    public void testing() {
         List<ScmsaPosTransRollup> list = factory.createHourlyStEntryFromRollUp(...);
         //TODO asserts and etc
    }

}

但是这个测试被认为是集成测试,因为它加载了整个spring上下文和bean相关。

另一种选择是(真实的)单元测试。使用构造函数而不使用@SpringBootTest,模拟依赖项(ModelMapper)。这使得测试更加快速和简单。

示例:

public class StoreIdAssignmentFactoryTest {

    @Test
    public void testing() {
         ModelMapper mapper = mock(ModelMapper.class);
         StoreIdAssignmentFactory factory = new StoreIdAssignmentFactory(mapper)
         List<ScmsaPosTransRollup> list = factory.createHourlyStEntryFromRollUp();
         //TODO asserts and etc
    }

}