mercredi 2 décembre 2015

Partial mocking a method of a subclass makes it bypass the superclass constructor

I'm trying to mock only a method (getValue) of a class (Collaborator) that extends another (Person). However, after setting the Expectations block, constructors of the mocked class are not executing super(...) when this method is called.

The following example is an adaptation from the code shown here: http://ift.tt/1OFJ6PM

The problem happens with the object Collaborator c3. The last assert fails, and I expected it to pass.

public class PartialMockingTest
{
   static class Person
   {
      final int id;

      Person() { this.id = -1; }
      Person(int id) { this.id = id; }

      int getId() { return id; }
   }          

   static class Collaborator extends Person
   {
       final int value;

       Collaborator() { value = -1; }
       Collaborator(int value) { this.value = value; }
       Collaborator(int value, int id) { super(id); this.value = value; }

       int getValue() { return value; }
       final boolean simpleOperation(int a, String b, Date c) { return true; }
   }

   @Test
   public void partiallyMockingAClassAndItsInstances()
   {
      final Collaborator anyInstance = new Collaborator();

      new Expectations(Collaborator.class) {{
         anyInstance.getValue(); result = 123;
      }};

      // Not mocked, as no constructor expectations were recorded:
      Collaborator c1 = new Collaborator();
      Collaborator c2 = new Collaborator(150);
      Collaborator c3 = new Collaborator(150, 20); 

      // Mocked, as a matching method expectation was recorded:
      assertEquals(123, c1.getValue());
      assertEquals(123, c2.getValue());
      assertEquals(123, c3.getValue());

      // Not mocked:
      assertTrue(c1.simpleOperation(1, "b", null));
      assertEquals(45, new Collaborator(45).value);
      assertEquals(20, c3.getId()); // java.lang.AssertionError: expected:<20> but was:<-1>
   }

}

Am I doing something wrong? Is it a bug?

Aucun commentaire:

Enregistrer un commentaire