在 JUnit 测试中使用 JMockit 多次模拟静态方法

发布于 2024-10-15 23:54:51 字数 1525 浏览 8 评论 0原文

我有一个带有静态方法的类,目前正在使用 JMockit 进行模拟。假设它看起来像这样:

public class Foo {
    public static FooValue getValue(Object something) {
        ...
    }
    public static enum FooValue { X, Y, Z, ...; }
}

我有另一个类(我们称之为 MyClass),它调用 Foo 的静态方法;我正在尝试为该类编写测试用例。我的 JUnit 测试使用 JMockit,看起来像这样:

public class MyClassTest extends TestCase {
    @NonStrict private final Foo mock = null;

    @Test public void testMyClass() {
        new Expectations() {
            {
                Foo.getValue((Object) any); result = Foo.FooValue.X;
            }
        };
    }

    myClass.doSomething();
}

这工作得很好,而且当测试执行时,我的 MyClass 实例在调用 Foo.getValue() 时将正确获取 Foo.FooValue.X 的枚举值。

现在,我尝试迭代枚举中的所有值,并重复运行测试。如果我将上面的测试代码放入 for 循环中并尝试将模拟静态方法的结果设置为每个枚举值,这是行不通的。当我迭代枚举时,Foo.getValue() 的模拟版本始终返回 Foo.FooValue.X,并且从不返回任何其他值。

如何在单个 JUnit 测试中多次模拟静态方法?我想做这样的事情(但显然它不起作用):

public class MyClassTest extends TestCase {
    @NonStrict private final Foo mock = null;

    @Test public void testMyClass() {

        for (final Foo.FooValue val : Foo.FooValue.values() {

            new Expectations() {
                {
                    // Here, I'm attempting to redefine the mocked method during each iteration
                    // of the loop. Apparently, that doesn't work.
                    Foo.getValue((Object) any); result = val;
                }
            };

            myClass.doSomething();
        }

    }
}

有什么想法吗?

I have a class with static methods that I'm currently mocking with JMockit. Say it looks something like:

public class Foo {
    public static FooValue getValue(Object something) {
        ...
    }
    public static enum FooValue { X, Y, Z, ...; }
}

I have another class (let's call it MyClass) that calls Foo's static method; I'm trying to write test cases for this class. My JUnit test, using JMockit, looks something like this:

public class MyClassTest extends TestCase {
    @NonStrict private final Foo mock = null;

    @Test public void testMyClass() {
        new Expectations() {
            {
                Foo.getValue((Object) any); result = Foo.FooValue.X;
            }
        };
    }

    myClass.doSomething();
}

This works fine and dandy, and when the test is executed my instance of MyClass will correctly get the enum value of Foo.FooValue.X when it calls Foo.getValue().

Now, I'm trying to iterate over all the values in the enumeration, and repeatedly run the test. If I put the above test code in a for loop and try to set the result of the mocked static method to each enumeration value, that doesn't work. The mocked version of Foo.getValue() always returns Foo.FooValue.X, and never any of the other values as I iterate through the enumeration.

How do I go about mocking the static method multiple times within the single JUnit test? I want to do something like this (but obviously it doesn't work):

public class MyClassTest extends TestCase {
    @NonStrict private final Foo mock = null;

    @Test public void testMyClass() {

        for (final Foo.FooValue val : Foo.FooValue.values() {

            new Expectations() {
                {
                    // Here, I'm attempting to redefine the mocked method during each iteration
                    // of the loop. Apparently, that doesn't work.
                    Foo.getValue((Object) any); result = val;
                }
            };

            myClass.doSomething();
        }

    }
}

Any ideas?

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

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

发布评论

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

评论(1

浅忆 2024-10-22 23:54:51

您应该在一次记录中记录多个连续的返回值,而不是“多次模拟该方法”:

public class MyClassTest extends TestCase
{
    @Test
    public void testMyClass(@Mocked Foo anyFoo)
    {
        new Expectations() {{
            Foo.getValue(any);
            result = Foo.FooValue.values();
        }};

        for (Foo.FooValue val : Foo.FooValue.values() {
            myClass.doSomething();
        }
    }
}

如果需要更大的灵活性,也可以使用 Delegate 来完成。

Instead of "mocking the method multiple times", you should record multiple consecutive return values in a single recording:

public class MyClassTest extends TestCase
{
    @Test
    public void testMyClass(@Mocked Foo anyFoo)
    {
        new Expectations() {{
            Foo.getValue(any);
            result = Foo.FooValue.values();
        }};

        for (Foo.FooValue val : Foo.FooValue.values() {
            myClass.doSomething();
        }
    }
}

It could also be done with a Delegate, if more flexibility was required.

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