>我有一个场景,我从另一个函数调用静态函数。在这种情况下,我们如何编写单元测试?
这是我的代码:
public class TradesHelper {
public static double calculatePL(Market market, Trade trade) {
double pl = (Helper.priceDifference(market, trade) / market.getSize()) * trade.getQuantity() * Helper.effectiveValue(market);
return pl;
}
}
public class Helper {
public static priceDifference(Market market, Trade trade) {
//Do something here
}
}
这就是我尝试编写单元测试用例的方式:
我已经为帮助程序类编写了一个单元测试用例。但是对于TradesHelper类,这就是我尝试编写的方式:
public class TradesHelperTest {
@Mock
Market market;
@Mock
Trade trade;
@Test
public void calculatePlFromPips_Test() {
//Trying to return a value when priceDifference function in Helper class is called
Helper helper1 = spy(new Helper());
doReturn(0.0012999999999999678).when(helper1).priceDifference(new Market(),new Trade());
}
但是我得到这样的错误:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
我是编写单元测试的新手。有人可以指导我如何写作吗?
谢谢
正如评论所说,你不能用纯粹的"香草">Mockito来嘲笑static
方法。
但是静态访问是一个糟糕的设计,应该避免。创建测试的问题证明静态访问使代码使用紧密耦合,因此难以重用(因为测试是一种"重用"...... 静态访问还有效地禁止了继承和多态性,这是我们使用OO语言的两个主要概念。
另一方面,没有规则规定"帮助程序类"或"实用程序类"(在它们提供通用行为的意义上)必须具有static
方法。这只是一种误解,因为只有静态方法的类过去被称为"实用程序类"。
因此,与其屈服于糟糕的设计并使用Powermock,不如将类Helper
和类TradesHelper
更改为非静态方法,并在生产代码中使用它们的对象。
Java毕竟是一种面向对象的编程语言,那么为什么要避免对象呢?
但不要在TradesHelper
内实例化Helper
。将Helper
的实例作为构造函数参数传递:
public class TradesHelper {
private final Helper helper;
public TradesHelper(Helper helper){
this.helper = helper;
}
public double calculatePL(Market market, Trade trade) {
// ...
public class TradesHelperTest {
@Mock
Market market;
@Mock
Trade trade;
@Mock
private Helper helper;
private TradesHelper tradesHelper; // class under test, no mock nor spy!
@Before
public void setup(){
tradesHelper= new TradeHelper(helper);
}
@Test
public void calculatePlFromPips_Test() {
// arrange
doReturn(0.0012999999999999678)
.when(helper)
.priceDifference(market,trade);// use mocks here not new objects
// act
tradesHelper.calculatePL(market,trade);
// assert
// either assertThat() or verify()
}
}