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?
As previously mentioned, since Mockito 3.4. 0, we can use the Mockito. mockStatic(Class<T> classToMock) method to mock invocations to static method calls. This method returns a MockedStatic object for our type, which is a scoped mock object.
If you need to mock a static method, it is a strong indicator for a bad design. Usually, you mock the dependency of your class-under-test. If your class-under-test refers to a static method - like java.
You can use Moq to mock non-static methods but it cannot be used to mock static methods.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With