简体   繁体   English

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

[英]Unable to call the function from the mocked component class

I have a junit test method as follows: 我有一个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());
    }
}

And My StoreIdAssignmentService class will be: 我的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);

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

    }
}

and My Factory class would be: 我的工厂班级将是:

@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;
    }
}

The StoreIdAssignmentService class contains the method "calculateStateForPosHourlyStTransaction" which calls some method in Factory class. StoreIdAssignmentService类包含方法“ calculateStateForPosHourlyStTransaction”,该方法调用Factory类中的某些方法。 When I debug as the junit test case , am not able to call that factory class method . 当我将调试作为junit测试用例时,无法调用该工厂类方法。 What I am doing wrong here. 我在这里做错了。 Can anyone please suggest me. 谁能建议我。

You are mocking the factory: 您在嘲笑工厂:

@Mock
private StoreIdAssignmentFactory storeIdAssignmentFactory;

So you can't investigate the method createHourlyStEntryFromRollUp inside the factory, because the whole factory is mocked: 因此,您无法研究工厂内部的方法createHourlyStEntryFromRollUp ,因为整个工厂都是createHourlyStEntryFromRollUp的:

storeIdAssignmentFactory.createHourlyStEntryFromRollUp

If you trying to debug the createHourlyStEntryFromRollUp and the StoreIdAssignmentFactory is a @Component (or @Service ), I recommend create a StoreIdAssignmentFactoryTest class test, use the @Autowired on it and @MockBean his dependencies. 如果您尝试调试createHourlyStEntryFromRollUp并且StoreIdAssignmentFactory@Component (或@Service ),则我建议创建一个StoreIdAssignmentFactoryTest类测试,在其上使用@Autowired并使用@MockBean其依赖项。

Example: 例:

@SpringBootTest
public class StoreIdAssignmentFactoryTest {

    @Autowired
    StoreIdAssignmentFactory factory;

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

}

But this test is considered a integration test, because it load the whole spring context and beans related. 但是此测试被认为是集成测试,因为它会加载整个spring上下文和与bean相关的内容。

Another alternative is the (true) unit test . 另一种选择是(true) 单元测试 Use your constructor and not use @SpringBootTest , mock the dependencies (ModelMapper). 使用您的构造函数,而不要使用@SpringBootTest ,模拟依赖项(ModelMapper)。 This makes the test more fast and simple. 这使测试更加快速和简单。

Example: 例:

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
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM