Java – a simulation method that uses jmock to type parameters

Background:

This is a jmock JUnit specific problem (these are the two technologies I have to use) Yes, what I want to do is with powermock, but this is an edge case that is not worth changing the tool No, sorry, I'm not asking this question to debate the philosophical validity of static methods:)

With this, I really appreciate anyone looking at this issue

Question:

I have some legacy code and I need to write a test (we're trying to test around inherited code to ensure that we don't break anything in a potentially large amount of refactoring... This is another story.)

Objectives:

The method I'm trying to simulate is foo in the following class Bar method, using jmock's class impasterizer facility (through junit4lockery.)

The following code represents the code I'm testing:

public class Foo {
     public abstract <T> void bar(
         Class<? extends T> paramClass,T paramT);

My test setup is designed to allow any call to bar () to receive a class instance (which obviously degenerates into class... Stupid Java type erasure "function") and pair with any instance of snafu

This is the key difference here I didn't pair two matcher parameters, or two literal parameters, but a literal (t.class) and a value of any type of T Jmock does not allow this, so the expected solution will be a matcher > and matcher:

Foo mock = context.mock(Foo.class);
context.checking(new Expectations() {
    // keep warnings close to the culprit code when possible
    @SuppressWarnings("unchecked")
    public void allow(final Foo mockedFoo) {
        allowing(mockedFoo).bar(
            with(any(Snafu.class.getClass())),// Matcher that *should* resolve to Class<?>
            with(any(Snafu.class)));  // matcher to anything of type Snafu.class
    }
    {
        allow(mockedFoo);
    }
});

Then, we inject the mocking foo, which is finally called by another class. I will be called the driver (* I will return to the static method call later):

// fooImpl has been replaced/injected with our mock
fooImpl.bar(Snafu.class,someStaticFunctionThatReturnsASnafu());

Question:

The problem is that when the driver calls the bar method on the mocked foo instance, my test encounters the following exception:

java.lang.IllegalArgumentException: not all parameters were given explicit matchers: either all parameters must be specified by matchers or all must be specified by values,*you cannot mix matchers and values*
    at org.jmock.internal.InvocationExpectationBuilder.checkParameterMatcherCount(InvocationExpectationBuilder.java:98)
    at org.jmock.internal.InvocationExpectationBuilder.createExpectationFrom(InvocationExpectationBuilder.java:91)
    at org.jmock.internal.InvocationToExpectationTranslator.invoke(InvocationToExpectationTranslator.java:19)
    at org.jmock.internal.FakeObjectMethods.invoke(FakeObjectMethods.java:38)
    at org.jmock.lib.legacy.ClassImposteriser$4.invoke(ClassImposteriser.java:129)
    at .....

Obviously (to me), the jmock matcher treats class instances as values, no matter how we try to match them Or did I miss something?

Java. Net is used in many applications A similar exception was encountered in a previous call to the lang.class parameter Obviously, anything that looks like X.class will be a value, not a new instance

But the problem here is that another parameter must be solved by a matcher, not just an actual value

[*] ideally, static method calls can be overridden

fooImpl.bar(Snafu.class,someStaticFunctionThatReturnsASnafu());

Some are more suitable for ridicule (non static methods, another object, or things injected into IOC)

Maybe this is the way we will eventually go, but the temporary code has a lot of static calls

I want to postpone until a more appropriate moment, but find a general jmock solution. If it exists, this allows me to set stupid functions, such as foo The necessary expectations of bar

Solution

If I'm not wrong, you did everything in your test case Jmock's documentation on terms

The important part here is to emphasize each You should only get the illegalargumentexception you mentioned,

If you mix a clause with a literal value – in your case

allowing(mockedFoo).bar(Class.class,with(any(Snafu.class)));

Including class Class is literal See here

I tested your code and it seems to work as expected This is my complete JUnit testcase:

import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JUnit4Mockery;
import junit.framework.TestCase;

public class FooTest extends TestCase{
    Mockery context = new JUnit4Mockery();

    public interface Foo {
        public abstract <T> void bar(Class<? extends T> paramClass,T paramT);
    }

    public static class Snafu {}

    public void testFoo() {
        final Foo mock = context.mock(Foo.class);
        context.checking(new Expectations() {
            // keep warnings close to the culprit code when possible
            @SuppressWarnings("unchecked")
            public void allow(final Foo mockedFoo) {
                allowing(mockedFoo).bar(
                        with(any(Class.class)),// Matcher that *should* resolve to Class<?>
                        with(any(Snafu.class)));  // matcher to anything of type Snafu.class
            }
            {
                allow(mock);
            }
        });

        // test bar method (two invocations)
        mock.bar(Snafu.class,someStaticFunctionThatReturnsASnafu());
        mock.bar(Snafu.class,someStaticFunctionThatReturnsASnafu());

    }

    public static Snafu someStaticFunctionThatReturnsASnafu() {
        return new Snafu();
    }
}

This test case is successful without any runtime exceptions (tested with JUnit 4 and jmock 2.6.0) I use (any (class. Class)) instead of (any (snafu. Class. Getclass())) readability, but it doesn't matter

I only get the mentioned illegalargumentexception if I change it to

allowing(mockedFoo).bar(Class.class,with(any(Snafu.class)));
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>