出于学校目的,我正在创建一个使用股票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来尝试实现这一点。
主类中的代码正在创建一个新的 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()
样式方法。
< 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();
//…
您可以使用然后删除()方法。下面是示例
@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调用时它应返回适当的