PowerMockito 模拟单个静态方法并返回对象

时间:2023-05-03
本文介绍了PowerMockito 模拟单个静态方法并返回对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我想从一个包含 2 个静态方法 m1 和 m2 的类中模拟一个静态方法 m1.我希望方法 m1 返回一个对象.

我尝试了以下

1)

PowerMockito.mockStatic(Static.class, new Answer<Long>() {@覆盖公共长答案(InvocationOnMock 调用)抛出 Throwable {返回 1000 升;}});

这同时调用了 m1 和 m2,它们具有不同的返回类型,因此它给出了返回类型不匹配错误.

2) PowerMockito.when(Static.m1(param1, param2)).thenReturn(1000l);但是在执行 m1 时不会调用它.

3) PowerMockito.mockPartial(Static.class, "m1");给出了 mockPartial 不可用的编译器错误,这是我从 http://code.google.com 获得的/p/powermock/wiki/MockitoUsage.

解决方案

你想做的是1的一部分和2的全部组合.

您需要使用 PowerMockito.mockStatic 为类的所有静态方法启用静态模拟.这意味着可以使用 when-thenReturn 语法对它们进行存根.

但是,您使用的 mockStatic 的 2 参数重载为 Mockito/PowerMock 在调用未在模拟实例上显式存根的方法时应该执行的操作提供了默认策略.

来自 javadoc:p><块引用>

创建具有指定策略的类模拟,以获取其答案互动.这是相当高级的功能,通常你不需要它编写体面的测试.但是,在使用时可能会有所帮助遗留系统.这是默认答案,因此仅在以下情况下使用你不会存根方法调用.

默认默认存根策略是只为对象、数字和布尔值方法返回 null、0 或 false.通过使用 2-arg 重载,您是在说不,不,不,默认情况下使用这个 Answer 子类的回答方法来获取默认值.它返回一个 Long,所以如果你有静态方法返回不兼容的东西长,有问题.

相反,使用 1-arg 版本的 mockStatic 来启用静态方法的存根,然后使用 when-thenReturn 指定对特定方法执行的操作.例如:

导入静态 org.mockito.Mockito.*;导入 org.junit.Test;导入 org.junit.runner.RunWith;导入 org.mockito.invocation.InvocationOnMock;导入 org.mockito.stubbing.Answer;导入 org.powermock.api.mockito.PowerMockito;导入 org.powermock.core.classloader.annotations.PrepareForTest;导入 org.powermock.modules.junit4.PowerMockRunner;类 ClassWithStatics {公共静态字符串 getString() {返回字符串";}公共静态 int getInt() {返回 1;}}@RunWith(PowerMockRunner.class)@PrepareForTest(ClassWithStatics.class)公共类 StubJustOneStatic {@测试公共无效测试(){PowerMockito.mockStatic(ClassWithStatics.class);when(ClassWithStatics.getString()).thenReturn("你好!");System.out.println("字符串:" + ClassWithStatics.getString());System.out.println("Int:" + ClassWithStatics.getInt());}}

String 值静态方法被存根返回Hello!",而 int 值静态方法使用默认存根,返回 0.

I want to mock a static method m1 from a class which contains 2 static methods, m1 and m2. And I want the method m1 to return an object.

I tried the following

1)

PowerMockito.mockStatic(Static.class, new Answer<Long>() {
         @Override
         public Long answer(InvocationOnMock invocation) throws Throwable {
            return 1000l;
         }
      });

This is calling both m1 and m2, which has a different return type, so it gives a return type mismatch error.

2) PowerMockito.when(Static.m1(param1, param2)).thenReturn(1000l); But this is not called when m1 is executed.

3) PowerMockito.mockPartial(Static.class, "m1"); Gives compiler error that mockPartial not available, which I got from http://code.google.com/p/powermock/wiki/MockitoUsage.

解决方案

What you want to do is a combination of part of 1 and all of 2.

You need to use the PowerMockito.mockStatic to enable static mocking for all static methods of a class. This means make it possible to stub them using the when-thenReturn syntax.

But the 2-argument overload of mockStatic you are using supplies a default strategy for what Mockito/PowerMock should do when you call a method you haven't explicitly stubbed on the mock instance.

From the javadoc:

Creates class mock with a specified strategy for its answers to interactions. It's quite advanced feature and typically you don't need it to write decent tests. However it can be helpful when working with legacy systems. It is the default answer so it will be used only when you don't stub the method call.

The default default stubbing strategy is to just return null, 0 or false for object, number and boolean valued methods. By using the 2-arg overload, you're saying "No, no, no, by default use this Answer subclass' answer method to get a default value. It returns a Long, so if you have static methods which return something incompatible with Long, there is a problem.

Instead, use the 1-arg version of mockStatic to enable stubbing of static methods, then use when-thenReturn to specify what to do for a particular method. For example:

import static org.mockito.Mockito.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

class ClassWithStatics {
  public static String getString() {
    return "String";
  }

  public static int getInt() {
    return 1;
  }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassWithStatics.class)
public class StubJustOneStatic {
  @Test
  public void test() {
    PowerMockito.mockStatic(ClassWithStatics.class);

    when(ClassWithStatics.getString()).thenReturn("Hello!");

    System.out.println("String: " + ClassWithStatics.getString());
    System.out.println("Int: " + ClassWithStatics.getInt());
  }
}

The String-valued static method is stubbed to return "Hello!", while the int-valued static method uses the default stubbing, returning 0.

这篇关于PowerMockito 模拟单个静态方法并返回对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:如何使用来自 64 位进程的 32 位 COM 对象? 下一篇:Mockito 如何仅模拟超类方法的调用

相关文章