Java 如何在没有powermock的情况下模拟静态方法
在JUnit中进行测试时,有没有办法模拟静态util方法 我知道Powermock可以模拟静态调用,但我不想使用Powermock 有其他选择吗?(我想你可以使用Mockito)我脑子里没有什么特别的想法,但在这种情况下,我倾向于使用以下策略: 1)在测试的类中,将静态直接调用替换为对封装静态调用本身的包级方法的调用:Java 如何在没有powermock的情况下模拟静态方法,java,unit-testing,junit,mockito,powermock,Java,Unit Testing,Junit,Mockito,Powermock,在JUnit中进行测试时,有没有办法模拟静态util方法 我知道Powermock可以模拟静态调用,但我不想使用Powermock 有其他选择吗?(我想你可以使用Mockito)我脑子里没有什么特别的想法,但在这种情况下,我倾向于使用以下策略: 1)在测试的类中,将静态直接调用替换为对封装静态调用本身的包级方法的调用: public class ToBeTested{ public void myMethodToTest(){ ... String
public class ToBeTested{
public void myMethodToTest(){
...
String s = makeStaticWrappedCall();
...
}
String makeStaticWrappedCall(){
return Util.staticMethodCall();
}
}
2)在测试和模拟包装包级别的方法时监视被测试的类:
public class ToBeTestedTest{
@Spy
ToBeTested tbTestedSpy = new ToBeTested();
@Before
public void init(){
MockitoAnnotations.initMocks(this);
}
@Test
public void myMethodToTestTest() throws Exception{
// Arrange
doReturn("Expected String").when(tbTestedSpy).makeStaticWrappedCall();
// Act
tbTestedSpy.myMethodToTest();
}
}
下面是我写的一篇关于间谍活动的文章,如果您需要更深入的了解,它包含了类似的案例:当您的静态代码给您的单元测试带来麻烦时;因此,你觉得你必须“模仿它”,你有这些选择:
- 你转向PowerMock(ito)。很好
- 你转向JMockit。也很好用
- 如果您正在测试自己编写的代码,您可能想退一步问问自己:“为什么我要编写现在很难进行单元测试的代码?”
所以:如果你能摆脱静态调用(即使只是使用另一个答案中建议的解决方法),那就更好了。如果不是:莫基托帮不上忙;你需要字节码操作的魔力。JVM代理 我很幸运地做了一些类似于Maciej在上面的回答中所建议的事情。在Java8中,我喜欢用函数接口包装这些静态方法,使它们更易于注入或模拟。例如:
public class MyClass {
private MyStaticWrapper staticWrapper;
public MyClass(final MyStaticWrapper staticWrapper) {
this.staticWrapper = staticWrapper;
}
public void main() {
...
staticWrapper.doSomething();
...
}
}
public interface MyStaticWrapper {
default void doSomething() {
Util.annoyingUntestableStaticFunction();
}
}
您可以使用
Mockito
(自版本)来模拟静态方法
给定一个类Foo
:
class Foo{
static String method() {
return "foo";
}
}
这就是测试:
@Test
void testMethod() {
assertEquals("foo", Foo.method());
try (MockedStatic mocked = Mockito.mockStatic(Foo.class)) {
mocked.when(Foo::method).thenReturn("bar");
assertEquals("bar", Foo.method());
mocked.verify(Foo::method);
}
assertEquals("foo", Foo.method());
}
这需要依赖项
org.mockito:mockito inline:3.4.0
或更新版本。即使使用mockito,也不能模拟静态方法。您不想使用powermock有什么原因吗?您必须模拟它吗?这是你的代码,你可以重写它,这样就不会有静态?我注意到你的问题仍然是“开放的”——因为你没有接受答案。请看一看,然后决定是否要回答。或者让我知道是否有什么我可以做的,以加强我的投入,使其值得接受。接受帮助未来的读者确定问题是否得到解决,并对花时间回答你的人表示感谢。谢谢@UweAllner,不使用PosiMoCK的一个原因是像JACCOO这样的代码覆盖工具可能不考虑通过代码覆盖报告中的PosiMoCK来覆盖代码。当问题明确地询问静态方法时,如何调用构造函数?当所有方法都是静态的时候调用构造函数不是没有用吗?此外,在这种情况下,监视也将是无用的。如果类不是final,他可以将子类添加到tobetest
中,添加包装器方法并测试子类。我得到一个错误想要但未调用:
,实际上,当我尝试验证是否调用了该方法时,没有与该模拟进行任何交互。
我使用org.mockito:mockito inline:3.4.0和更新版本,并复制了与上述相同的代码。但我仍然得到“MockedStatic”和“mockStatic”的编译错误。它不显示任何导入语句。我尝试使用import org.mockito.*;但在使用编辑过的答案后,它也不起作用,我得到了编译错误,因为“MockedStatic无法解析为类型”。我们需要特殊的进口声明吗。我的pom.xml依赖项添加为org.mockito mockito inline 3.5.9@user2000189您使用的是SpringBoot
?最新版本的spring boot
(2.3.3.版本)不支持Mockito 3.4.0。如果您想使用它,您需要将org.mockito:mockito core
强制到3.4.0版。我使用的是spring boot(2.3.1-RELEASE)和mockito core作为3.3.3。@user2000189将mockito core
强制到3.4.0版可以让您运行这个示例,但是要注意其他潜在的问题,因为Spring还没有正式支持它。您好,您有关于这个的单元测试的例子吗?