Junit Mocking投掷空指针

时间:2018-11-10 22:14:51

标签: junit mockito

我正在尝试模拟以下服务类。

我已经创建了一个我正在调用的单独的Config bean,如下面的代码所示:-

@Component
public class CrawlerService implements CrawlerServiceInterface {

    private static final Logger LOGGER = LoggerFactory.getLogger(CrawlerService.class);

    private final CrawlConfig config;

    @Autowired
    CrawlerFactory crawlerFactory;

    @Autowired
    public CrawlerService(@Qualifier(value = "CrawlerConfig") CrawlConfig config) {
        this.config = config;
    }

    @Value("${com.prudential.noOfCrawlers}")
    private int numberOfCrawlers;

    @Override
    public Object crawlService(String URL, int max) throws Exception {

        LOGGER.info("In Service Class");

        this.config.setMaxPagesToFetch(max);

        PageFetcher pageFetcher = new PageFetcher(config);
        RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
        RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
        CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);

        controller.addSeed(URL);
        controller.start(crawlerFactory, numberOfCrawlers);

        List<Object> crawlersLocalData = controller.getCrawlersLocalData();

        LOGGER.info("End of Service Class");
        return crawlersLocalData;

    }

}

问题是我在this.config.setMaxPagesToFetch中得到了空指针异常。

我在做什么错?

如果我用@Mock注释嘲笑了一些相关对象,这是否意味着不允许更改值?

这是测试班:-

List<Object> obj=new ArrayList<Object>();

@Mock
private CrawlConfig config;

@Mock
CrawlerFactory crawlerFactory;

@Mock
CrawlController controller;

@InjectMocks
CrawlerService crawlerService = new CrawlerService(config);

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
}

@Test
public void testService() throws Exception {
    when(controller.getCrawlersLocalData()).thenReturn(obj);

    assertEquals(crawlerService.crawlService("https://vogella.com", 10), obj);

}

1 个答案:

答案 0 :(得分:0)

这里您有模拟创建顺序的问题。首先,让我们看看这里发生了什么:

  • 首先,您要声明一些字段。在这种情况下,您要声明private CrawlConfig configCrawlerService crawlerService。但是crawlerService不仅要声明,还要初始化。
  • 初始化它时,将作为对它的依赖CrawlConfig config(即null)传递。
  • 然后MockitoAnnotations.initMocks(this)开始神奇。它有什么作用?它初始化所有带有@Mock注释的字段,然后尝试初始化@InjectMocks(如果尚未初始化)。就您而言,它已被初始化,因此模仿者不会对其进行初始化,而将使用您创建的实例。
  • 之后,将进行模拟注入。 Mockito将尝试使用其任何一种策略来注入模拟。您可以在@InjectMocks javadoc中了解更多信息。因此,在您的情况下,mockito将尝试使用属性设置器或字段注入。但是,您的CrawlConfig config中的CrawlerService被声明为final,并且mockito将忽略此字段,因为这种注入类型mockito会忽略{{1} }或final字段。

因此,您在这里创建了一个具有static依赖项CrawlerService的{​​{1}}实例,而CrawlConfig config对此没有任何作用。

1)您可以在null进行以下操作之前自己模拟mockito

CrawlConfig config

2)您可以省略mockito的初始化并依靠private CrawlConfig config = Mockito.mock(CrawlConfig.class); @InjectMocks CrawlerService crawlerService = new CrawlerService(config);

CrawlerService

这些方法中的每一个都应该起作用。

您也可以从mockito中删除@Mock private CrawlConfig config = Mockito.mock(CrawlConfig.class); @InjectMocks CrawlerService crawlerService; 声明,它也将起作用。但是对我来说,以上两种方法是更好的选择。