title: Mocking Method that Takes a Class<?> Type Argument with JMock
body: <h1>Background:</h1>
  
  <p>This is a JMock+JUnit specific question (those are the two technologies <strong>I must</strong> use). Yes, what I want to do can be done with PowerMock, but this is an edge case that doesn't warrant changing of tools. And no, sorry, I'm not asking this question to debate the philosophical validity of static methods :)</p>
  
  <p>With that out of the way, I will really thank anyone taking a look at this question.</p>
  
  <h1>Question:</h1>
  
  <p>I have piece of legacy code that I need to write a test for (we are trying to put tests around inherited code to ensure we don't break anything during a potentially massive refactoring effort... that's a tale for another time.)</p>
  
  <h1>Goal:</h1>
  
  <p>The method I'm trying to mock is the <code>Foo.bar</code> method in the class below using JMock's class imposterizer facility (via <a href="http://jmock.org/javadoc/jmock-2.6.0/doc/org/jmock/integration/junit4/JUnit4Mockery.html">JUnit4Mockery</a>.) </p>
  
  <p>The code below is representative to the code I'm test-wrapping:</p>
  
  <pre><code>public class Foo {
       public abstract &lt;T&gt; void bar(
           Class&lt;? extends T&gt; paramClass, T paramT);
  </code></pre>
  
  <p>My test setup aims to allow any # of calls to <code>bar()</code> receiving a Class instance (which obviously degenerates to Class ... silly Java type erasure "feature"), paired with any instance of Snafu.</p>
  
  <p>That is the key distinction here. I'm not pairing two <a href="http://jmock.org/matchers.html">Matcher</a> parameters, or two literal parameters, but one literal (T.class) and any value of type T. JMock does not allow this, so the expected <em>solution</em> would be to have a Matcher> and a Matcher:</p>
  
  <pre><code>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&lt;?&gt;
              with(any(Snafu.class)));  // matcher to anything of type Snafu.class
      }
      {
          allow(mockedFoo);
      }
  });
  </code></pre>
  
  <p>Then, we inject the mocked Foo, which eventually gets called like this by another class, which I'll refer to as the <code>Driver</code> (*I'll get back to the static method call later):</p>
  
  <pre><code>// fooImpl has been replaced/injected with our mock
  fooImpl.bar(Snafu.class, someStaticFunctionThatReturnsASnafu()); 
  </code></pre>
  
  <h1>Problem:</h1>
  
  <p>The problem is that when the <code>Driver</code> invokes the <code>bar</code> method on the mocked <code>Foo</code> instance, my test encounters the following exception:</p>
  
  <pre><code>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 .....
  </code></pre>
  
  <p>Apparently (or so it looks to me), JMock matchers' see <code>Class</code> instances as values, regardless of how we try to match them. Or am I missing something?</p>
  
  <p>I'm encountering similar exceptions in many legacy calls that take a <code>java.lang.Class</code> argument. Obviously, anything that looks like <code>X.class</code> will be a value, not a new instance.</p>
  
  <p>But therein lies the problem because the other argument must be resolved with a matcher, not just with an actual value.</p>
  
  <hr>
  
  <p>[*] Ideally one could rewrite the static method call in </p>
  
  <pre><code>fooImpl.bar(Snafu.class, someStaticFunctionThatReturnsASnafu()); 
  </code></pre>
  
  <p>with something more amenable to mocking (a non-static method, another object or something injected with a IoC). </p>
  
  <p>Probably that is the way we will eventually go, but for the time being, the code in question has a significant number of static calls. </p>
  
  <p>I would like to defer that till a more appropriate moment, and instead find a general JMock solution, if one exists, that allows me to set the necessary expectations of mocking functions that like <code>Foo.bar</code> above.</p>