mac*_*roo 8 java unit-testing powermockito
我正在尝试测试一个使用带有许多静态方法的计算器类的类.我以类似的方式成功地嘲笑了另一个班级,但是这个班级更加顽固.
似乎如果mocked方法包含对传入的参数之一的方法调用,则静态方法不会被模拟(并且测试中断).删除内部呼叫显然不是一种选择.有什么明显的东西我在这里不见了吗?
这是一个浓缩版本,行为方式相同......
public class SmallCalculator {
public static int getLength(String string){
int length = 0;
//length = string.length(); // Uncomment this line and the mocking no longer works...
return length;
}
}
Run Code Online (Sandbox Code Playgroud)
这是测试......
import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.solveit.aps.transport.model.impl.SmallCalculator;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class SmallTester {
@Test
public void smallTest(){
PowerMockito.spy(SmallCalculator.class);
given(SmallCalculator.getLength(any(String.class))).willReturn(5);
assertEquals(5, SmallCalculator.getLength(""));
}
}
Run Code Online (Sandbox Code Playgroud)
似乎对这个问题存在一些困惑,所以我设计了一个更"现实"的例子.这个添加了一个间接级别,因此我似乎没有直接测试模拟方法.SmallCalculator类保持不变:
public class BigCalculator {
public int getLength(){
int length = SmallCalculator.getLength("random string");
// ... other logic
return length;
}
public static void main(String... args){
new BigCalculator();
}
}
Run Code Online (Sandbox Code Playgroud)
这是新的测试类......
import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.solveit.aps.transport.model.impl.BigCalculator;
import com.solveit.aps.transport.model.impl.SmallCalculator;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class BigTester {
@Test
public void bigTest(){
PowerMockito.spy(SmallCalculator.class);
given(SmallCalculator.getLength(any(String.class))).willReturn(5);
BigCalculator bigCalculator = new BigCalculator();
assertEquals(5, bigCalculator.getLength());
}
}
Run Code Online (Sandbox Code Playgroud)
mac*_*roo 17
我在这里找到了答案https://blog.codecentric.de/en/2011/11/testing-and-mocking-of-static-methods-in-java/
这是最终的代码.我已经在原始代码(以及人为的例子)中测试了这种方法,并且效果很好.Simples ...
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class BigTester {
@Test
public void bigTest(){
PowerMockito.mockStatic(SmallCalculator.class);
PowerMockito.when(SmallCalculator.getLength(any(String.class))).thenReturn(5);
BigCalculator bigCalculator = new BigCalculator();
assertEquals(5, bigCalculator.getLength());
}
}
Run Code Online (Sandbox Code Playgroud)