PowerMock、mockito、验证静态方法

发布于 2024-10-21 19:05:12 字数 1804 浏览 7 评论 0原文

我正在尝试让 PowerMock 与mockito一起使用,并且我正在关注此处的文档: http://code.google.com/p/powermock/wiki/MockitoUsage13

为了简化一点,假设我有一个静态方法:

StaticObj.put(String key, String val) { ... }

并且要测试的类执行如下操作:

public class ClassToTest {
    public void doSomething(Params p) {
        if (StringUtils.isNotBlank(p.getK()) StaticObj.put("k1", p.getK());
        if (StringUtils.isNotBlank(p.getX()) StaticObj.put("x1", p.getX());
    }
}

在我的单元测试中,我想验证当 K 和 X 不为空时是否调用 StaticObj.put或 null,所以我做了这样的事情:

public void testNormalCase() {
    // assume that mocking setup for statics already happened in some @Before function..
    Params params = new Params("k", "x");
    ClassToTest classToTest = new ClassToTest();
    classToTest.doSomething(params);

    // now I want to verify:
    PowerMockito.verifyStatic(times(1));
    StaticObj.put("k1", "k1");

    PowerMockito.verifyStatic(times(1));
    StaticObj.put("x1", "x");
}

这有效,这就是我所期望的。不起作用的是,如果我注释掉 K 的验证,那么 X 的验证就会失败!错误消息表明应为 ("x1", "x"),但得到的是 ("k1", "k")。这是为什么呢?我这个编码不正确吗?

它还让我相信,通过的以下类型的测试可能完全因错误的原因而通过:

public void testOtherCase() {
    // assume that mocking setup for statics already happened in some @Before function..
    Params params = new Params("k", null);
    ClassToTest classToTest = new ClassToTest();
    classToTest.doSomething();

    // now I want to verify:

    PowerMockito.verifyStatic(never());
    StaticObj.put(eq("x1"), anyString());
}

例如,我想知道 powermock 是否看到“k1”,决定“x1”从未被调用,并通过。 (?)

一般来说,我有一个被调用 N 次的静态方法(其中 N 根据输入参数而变化)。我想验证它是否在正确的情况下被调用(可以通过输入参数确定)。看来 powermock 不能很好地处理这个问题,除非我误解了。

感谢您的任何想法!

I'm trying to get PowerMock to work with mockito, and I'm following the documentation here: http://code.google.com/p/powermock/wiki/MockitoUsage13.

To simplify a bit, lets say that I have a static method:

StaticObj.put(String key, String val) { ... }

And the class to be tested does something like this:

public class ClassToTest {
    public void doSomething(Params p) {
        if (StringUtils.isNotBlank(p.getK()) StaticObj.put("k1", p.getK());
        if (StringUtils.isNotBlank(p.getX()) StaticObj.put("x1", p.getX());
    }
}

In my unit test I'd like to verify that StaticObj.put is called for K and X when they are not blank or null, so I do something like this:

public void testNormalCase() {
    // assume that mocking setup for statics already happened in some @Before function..
    Params params = new Params("k", "x");
    ClassToTest classToTest = new ClassToTest();
    classToTest.doSomething(params);

    // now I want to verify:
    PowerMockito.verifyStatic(times(1));
    StaticObj.put("k1", "k1");

    PowerMockito.verifyStatic(times(1));
    StaticObj.put("x1", "x");
}

This works, and it's what I'd expect. What doesn't work, is if I comment out the verification for K, then the verification for X fails! The error message indicates that ("x1", "x") is expected but got ("k1", "k"). Why is this? Am I not coding this correctly?

Also it leads me to believe that the following type of test, which passes, might pass for the wrong reason entirely:

public void testOtherCase() {
    // assume that mocking setup for statics already happened in some @Before function..
    Params params = new Params("k", null);
    ClassToTest classToTest = new ClassToTest();
    classToTest.doSomething();

    // now I want to verify:

    PowerMockito.verifyStatic(never());
    StaticObj.put(eq("x1"), anyString());
}

E.g. I wonder if powermock sees "k1", decides that "x1" was never called, and passes. (?)

To state it generally, I have a static method that is called N times (where N changes depending on the input params). And I want to verify that it was called in the correct cases (which can be determined by input params). It seems like powermock doesn't handle this well, unless I misunderstand.

Thanks for any ideas!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梨涡少年 2024-10-28 19:05:12

我仔细阅读了这个问题和问题,但不确定我是否清楚地理解了它们 - 根据我的理解,当您传递 k 和 x 但仅验证 k 时,powermock 引发异常是正确的。

因为您正在模拟静态方法 StaticObj.put,所以当您传递参数 k 和 x 并使用验证它时,

PowerMockito.verifyStatic(times(1));
StaticObj.put("k1", "k1");

PowerMockito.verifyStatic(times(1));
StaticObj.put("x1", "x"); 

这应该可以工作。当您验证参数 k 和 x 时,k 的验证将被注释掉。

// PowerMockito.verifyStatic(times(1));
// StaticObj.put("k1", "k1");

PowerMockito.verifyStatic(times(1));
StaticObj.put("x1", "x");

Powermock 显然会首先使用 put("k1"...) 进行调用,因此 x 的验证会引发错误。您的验证过程已按顺序进行。

I read this question and the issue carefully but not sure if I understood them clearly - From my understanding, it's correct that powermock raise the exception when you pass k and x but only verify k.

Because you are mocking the static method StaticObj.put, when you pass parameter k and x and verify it with

PowerMockito.verifyStatic(times(1));
StaticObj.put("k1", "k1");

PowerMockito.verifyStatic(times(1));
StaticObj.put("x1", "x"); 

This should work. And when you verify parameter k and x with verification for k is commented out.

// PowerMockito.verifyStatic(times(1));
// StaticObj.put("k1", "k1");

PowerMockito.verifyStatic(times(1));
StaticObj.put("x1", "x");

Powermock will get the invocation with put("k1"...) first apparently, so the verification of x will raise an error. Your verification process is sequenced.

瑾夏年华 2024-10-28 19:05:12

我不知道哪个版本,但 PowerMockito.verifyStatic(VerificationMode) 已弃用。只是想向在上一篇文章发布后几年发现的其他人指出这一点。

I don't know as of which version, but PowerMockito.verifyStatic(VerificationMode) is deprecated. Just wanted to point that out to anyone else finding this years after the last post.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文