【问题标题】:Verify call to static method验证对静态方法的调用
【发布时间】:2016-05-13 07:33:38
【问题描述】:

我想验证 public static void 方法已被调用

@RunWith(PowerMockRunner.class)
@PrepareForTest({ConsoleLog.class})
public class AdContentDataUnitTest {

    @Before
    public void setUp() throws Exception {
        PowerMockito.mockStatic(ConsoleLog.class);
    }

    @Test
    public void adContentData_sendTrackingEvent_noUrl() throws Exception {
        mAdContentData = spy(mAdContentData);

        // PowerMockito.doNothing().when(ConsoleLog.class);

        verifyStatic();
        mAdContentData.sendTrackingEvent("event1");
        //verifyStatic();
    }
}

sendTrackingEvent 将被调用,ConsoleLog.v(String, String) 将被调用。我在调试中可以看到调用了静态方法,但是出现以下日志并且测试失败:

Wanted but not invoked com.example.logger.ConsoleLog.v(
    "AdContentData",
    "sendTrackingEvent: event event1 does not exist."
);

我尝试在相同的日志之后添加verifyStatic,如果我删除第一个验证,则不会检查任何内容。如果我模拟整个 ConsoleLog 类,则会出现错误Unfinished stubbing detected here: [...] PowerMockitoCore.doAnswer

有人知道如何正确操作吗?

【问题讨论】:

    标签: java junit mockito powermockito


    【解决方案1】:

    有谁知道正确的做法吗?

    是的。根本不要这样做。

    假设你有一个类调用这样的静态方法:

    class Person {
        private final int id;
    
        Person() {
            id = IdGenerator.gen();
        }
    }
    

    将静态调用提取到非静态方法:

    class Person {
        private final int id;
    
        Person() {
            id = generateId();
        }
    
        protected int generateId() {
            return IdGenerator.gen();
        }
    }
    

    现在您可以编写一个测试,覆盖提取的方法:

        final int id = 1;
        Person person = new Person() {
            @Override
            protected int generateId() {
                return id;
            }
        };
    
        // test with person, knowing we control id
    

    但理想的解决方案实际上是重构被测代码,根本不使用这种静态调用,而是依赖注入。

    【讨论】:

    • 这是一个解决方案,但它会降低性能,因为我们需要多调用一个方法(我在 Android 上,性能很重要)
    • 编译器可以很好地内联此类方法调用。你确定它会产生显着的性能差异吗?你量过吗?我忘了提到理想的解决方案是重构被测代码以不使用静态调用而是使用依赖注入
    • 好吧,ConsoleLogdeveloper.android.com/reference/android/util/Log.html 的包装类
    • 我看到这是在 Android 上,所以也许你不能注入它。所以你可以忽略我关于依赖注入的建议。但是“提取和覆盖”技术建议仍然有效。单一的间接方式不太可能在性能方面产生影响,在被证明有罪之前假定无罪是合理的(基准测量显示出不可忽略的差异)
    猜你喜欢
    • 2019-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    相关资源
    最近更新 更多