Class Mock<T>

java.lang.Object
io.github.valentinherrmann.levenshtein.Mock<T>
Type Parameters:
T - the type of the class being mocked

public final class Mock<T> extends Object
An object of a student class whose methods the test can replace, and which records every call to its methods. Created with ClassWrapper.mock(); used to keep tests independent: a mistake in one student method then only fails the tests of that method.
Mock<?> guitarist = guitaristWrapper.mock()
        .override(guitaristWrapper.calculateLoudness, args -> (int) args[0] * 7);
Object drummer = drummerWrapper.newObjWithoutConstructor();
drummerWrapper.guitarist.setValue(drummer, guitarist.obj());
assertThat(drummerWrapper.calculateLoudness.invokeOnSpecificObject(drummer, 5, 3)).isEqualTo(38);
guitarist.assertCalled(guitaristWrapper.calculateLoudness, 1);
  • The object is an instance of a generated subclass. No constructor of the student class runs, so all attributes keep their default values (0, false, null); set them with AttributeWrapper.setValue(Object, Object) if needed.
  • An overridden method runs the test's function. Every other method runs the student's code (supervised by Ares as usual), or returns its default value after othersReturnDefaults().
  • Methods are matched by the method the wrapper actually found, so a misspelt but tolerated name is still overridden. Calls from the student's own code (this.getCount()) are intercepted, too.
  • Every call of a method that can be overridden is counted, and the arguments of the first 1000<T> calls per method are recorded (arrays as copies, other objects as references), see callCount(MethodWrapper), calls(MethodWrapper) and assertCalled(MethodWrapper, int).
  • Not possible: final classes and methods, records, enums, sealed classes, static and private methods, constructors, and attributes read directly by student code.
  • Field Details

    • MAX_RECORDED_CALLS

      public static final int MAX_RECORDED_CALLS
      Calls per method whose arguments are kept; further calls are only counted.
      See Also:
  • Method Details

    • override

      public Mock<T> override(MethodWrapper<?,?> method, Function<Object[],Object> function)
      Replaces a method: every call of it runs function instead of the student's code. The function gets the arguments converted to the parameter types the wrapper expects (e.g. an int as Integer, also if the student declared long). Its result is converted to the student's return type (numeric types are converted, e.g. an Integer for a double method) and ignored for void methods. If the function throws (or returns null for a primitive return type), the call fails like a call that throws. The function runs as test code: Ares does not restrict it, but it is called from student code, so keep it to plain computations.

      A method that is missing fails with the usual message. A method that cannot be overridden (final, static, private, or one of another class) fails with a readable message.

      Parameters:
      method - a method of the mocked class or of one of its superclasses or interfaces
      function - computes the return value from the arguments
      Returns:
      this mock
    • returning

      public Mock<T> returning(MethodWrapper<?,?> method, Object value)
      Replaces a method by one that always returns value.
      Parameters:
      method - a method of the mocked class or of one of its superclasses or interfaces
      value - the value to return (converted like the result of override(MethodWrapper, Function))
      Returns:
      this mock
    • othersReturnDefaults

      public Mock<T> othersReturnDefaults()
      Makes this a full mock: methods without override return their default value (0, false, null) instead of running the student's code. Their calls are still recorded. equals, hashCode and toString without override behave like those of Object (identity), so the object still works in lists, sets and messages.
      Returns:
      this mock
    • obj

      public Object obj()
      The object of the mock, created on the first call (without running a constructor) and the same afterwards. Overrides added later apply to it as well.
      Returns:
      the object, an instance of a generated subclass of the mocked class
    • callCount

      public long callCount(MethodWrapper<?,?> method)
      How often a method was called on obj() (or on a clone of it).
      Parameters:
      method - a method of the mocked class or of one of its superclasses or interfaces
      Returns:
      the number of calls
    • calls

      public List<Object[]> calls(MethodWrapper<?,?> method)
      The recorded calls of a method on obj(), in call order: the first 1000<T> calls, see callCount(MethodWrapper) for the number of all calls. Arrays were copied when the call was recorded; other objects are the ones passed.
      Parameters:
      method - a method of the mocked class or of one of its superclasses or interfaces
      Returns:
      the arguments of each call, converted to the parameter types the wrapper expects where they fit (a value that does not fit, e.g. 2.5 for a student's float where int is expected, is returned as passed)
    • assertCalled

      public void assertCalled(MethodWrapper<?,?> method, int times)
      Fails unless the method was called exactly times times on obj(). The message shows the arguments of the recorded calls.
      Parameters:
      method - a method of the mocked class or of one of its superclasses or interfaces
      times - the expected number of calls
    • assertCalled

      public void assertCalled(MethodWrapper<?,?> method, int times, Supplier<String> context)
      Like assertCalled(MethodWrapper, int), but the text of context is put in front of the failure message, e.g. which call of the method under test should have called this method.
      Parameters:
      method - a method of the mocked class or of one of its superclasses or interfaces
      times - the expected number of calls
      context - supplies the text shown in front of the failure message (may be null)
    • assertNotCalled

      public void assertNotCalled(MethodWrapper<?,?> method)
      Fails if the method was called on obj().
      Parameters:
      method - a method of the mocked class or of one of its superclasses or interfaces
    • resetCalls

      public void resetCalls()
      Forgets all recorded calls, e.g. after preparing the object.