当前位置: 首页 > 知识库问答 >
问题:

模拟使用参数模拟新实例调用

湛文乐
2023-03-14

出于学校目的,我正在创建一个使用股票API的应用程序。

我正在尝试为一种获取过去10年所有股票数据方法编写一个测试。我不想实际获取所有这些数据,而是想抛出一个异常。

我想测试的方法:

@Override
public List<StockData> getAllTeslaStockData() throws AlphaVantageException {
    List<StockData> stockData;

    AlphaVantageConnector apiConnector = new AlphaVantageConnector(APIKEY, TIMEOUT);
    TimeSeries stockTimeSeries = new TimeSeries(apiConnector);

    try {

        Daily responseDaily = stockTimeSeries.daily("TSLA", OutputSize.FULL);
        stockData = responseDaily.getStockData();

    } catch (AlphaVantageException e) {

        LOGGER.log(Level.SEVERE, "something went wrong: ", e);

        throw e;

    }

    return stockData;
}

股票时间系列(....)调用可以抛出阿尔法仓位异常。

我这样嘲弄了TimeSeries类:

TimeSeries stockTimeSeries = mock(TimeSeries.class);

在我的测试类中,我想模拟这个调用,并返回一个异常而不是实际数据。

when(stockTimeSeries.daily("TSLA", OutputSize.FULL)).thenThrow(new AlphaVantageException("No stock data available"));

无论我多么试图嘲笑这段代码,它永远不会抛出异常。它将始终只执行代码,并返回有效的股票数据,而不是像我尝试的那样抛出异常。

我如何模拟这段代码,以便它抛出我期望的测试异常。

AlphaVantageConnector、TimeSeries和Daily类是用于访问库存API的库的一部分,因此我无法更改这些类。

我正在使用JUnit 4.12和Mockito来尝试实现这一点。

共有3个答案

刘才俊
2023-03-14

主类中的代码正在创建一个新的 TimeSeries 实例,每次调用此方法时都会使用该实例,因此模拟的 TimeSeries 对象根本没有被使用。

TimeSeries stockTimeSeries = new TimeSeries(apiConnector);  // --> This is not getting mocked

    try {

        Daily responseDaily = stockTimeSeries.daily("TSLA", OutputSize.FULL);
        stockData = responseDaily.getStockData();

    }

您应该在类中创建另一个方法(如果它更满足 SOLID 原则,甚至可以创建一个单独的类),该方法将返回 TimeSeries 对象。像这样:-

<access modifier> TimeSeries getTimeSeries(...) {

}

然后这个方法应该在Junit中被模拟,当被模拟时,它应该返回模拟的时间序列引用(在TimeSeries stockTimeSeries=mock(TimeSeries.class);中创建)。您需要在主类上使用. spy()(除非您使用不同的类来创建TimeSeries对象)以便能够模拟特定的方法TimeSeries()而不是其他方法。

MainClass mainObject = Mockito.spy(new MainClass());
Mockito.when(mainObject.getTimeSeries()).thenReturn(stockTimeSeries);

然后,该方法调用stockTimeSeries。daily()将被现有代码所模仿:

when(stockTimeSeries.daily("TSLA", OutputSize.FULL)).thenThrow(new AlphaVantageException("No stock data available"));

注意:您还应该考虑使用。Mockito API在模拟时提供的anyString()样式方法。

陈嘉荣
2023-03-14

< code>TimeSeries对象是在方法本身中创建的,所以您不能模仿它——模仿是为了模仿成员。

你可以做的是这样做

class YourClass {
   private Supplier<TimeSeries> seriesCreator = () -> {
       return new TimeSeries(new AlphaVantageConnector(APIKEY, TIMEOUT));
   }

用于在方法中创建系列

@Override
public List<StockData> getAllTeslaStockData() throws AlphaVantageException {
    TimeSeries stockTimeSeries = seriesCreator.get();

现在,您可以嘲笑< code >供应商。

@Mock Supplier<TimeSeries> seriesCreatorMock;
@InjectMocks MyClass sut;

并在您的测试中

@Test(expected = AlphaVantageException.class)
void testException() {
    when(seriesCreatorMock.get()).thenThrow(new AlphaVantageException());
    sut.getAllTeslaStockData()
}

编辑:正如Angkur在评论中建议的那样,干净的方法是

class SeriesCreator implements Supplier<TimeSeries> {
    public TimeSeries get() {
       return new TimeSeries(new AlphaVantageConnector(APIKEY, TIMEOUT));
    }
}

class YourClass {
   private Supplier<TimeSeries> seriesCreator = new SeriesCreator();

//…

边健
2023-03-14

您可以使用然后删除()方法。下面是示例

@Test(expected = NullPointerException.class)
public void whenConfigNonVoidRetunMethodToThrowEx_thenExIsThrown() {
    MyDictionary dictMock = mock(MyDictionary.class);
    when(dictMock.getMeaning(anyString()))
      .thenThrow(NullPointerException.class);
 
    dictMock.getMeaning("word");
 类似资料:
  • 问题内容: 我正在尝试使用富有想象力的Mock测试库测试Django应用程序时模拟某些东西。我似乎无法完全正常工作,我正在尝试这样做: 我究竟做错了什么? 问题答案: 啊,我对在哪里应用该补丁装饰感到困惑。固定:

  • 我试图在测试中模拟一个调用,但我得到了一个错误,因为它调用了真正的方法,而不是模拟它。 这是我的方法 } 这是我的测试课 测试实际上调用了受保护的方法config Setter,并在设置代理时失败。帮助我理解我在这里做错了什么。

  • 我试图为一个类编写一个单元测试,这个类使用带有库中的的Google vision API。问题是,由于某种原因,我的模拟仍然调用真正的方法,然后抛出一个NPE,这破坏了我的测试。我以前从未在模拟上见过这种行为,我想知道我是不是做错了什么,是不是Spock/Groovy中有bug,还是与Google lib有关?

  • 我试图模拟对resttemplate.exchange()的调用,但无法使其工作。当前,对exchange()的调用挂起,所以我认为正在调用的是实际的方法,而不是我的模拟方法。对exchange()的调用如下:

  • 问题内容: 我正在尝试编写一个JUnit测试用例,用于测试助手类中的方法。该方法使用REST调用外部应用程序,而这正是我试图在JUnit测试中模拟的调用。 helper方法使用Spring的RestTemplate进行REST调用。 在测试中,我创建了一个模拟REST服务器和一个模拟REST模板,并按如下所示实例化它们: 然后,我给模拟服务器添加种子,以便当助手方法进行REST调用时它应返回适当的