Search code examples
javamockitojunit4

jUnit, Mockito. How to ensure a method in abstract class (a templae method) invokes the abstract hook method?


Here I go:

abstract class IdentifiedEntity<E extends IdentifiedEntity> implements Cloneable {
  ...
  public void updateWith(E that) {
    if (this != that) {
      if (that.isNew()) {
        throw new IllegalArgumentException("Cannot update with a new entity");
      }
      if (this.isNew()) {
        throw new IllegalStateException("Cannot update a new entity");
      }
      if (this.getId() != that.getId()) {
        throw new IllegalArgumentException("IDs do not match");
      }
      doUpdateWith(that);
    }
  }

  abstract void doUpdateWith(E that);
  ...
}

public final class User extends IdentifiedEntity<User> {
  ...
  @Override
  void doUpdateWith(User that) {
    assert that != null;
    this.name = that.name;
    this.email = that.email;
    System.arraycopy(that.password, 0, password, 0, password.length);
    this.enabled = that.enabled;
    this.caloriesPerDayLimit = that.caloriesPerDayLimit;
  }
  ...
}

The question is how can I unit test the updateWith(...) to ensure that it definely invokes the abstract doUpdateWith(...) implmented in the descendant (yes, for sure,if i tpasse sall the checks)?

That you guys!


Solution

  • With the help of @CoronA, I found the answer. Here it is:

    @Test
    public void updateWith() {
      User user = this.user.clone().setId(100);
      User mock = Mockito.spy(user);
      mock.updateWith(user);
      Mockito.verify(mock).doUpdateWith(user);
    }
    

    Thank you guys a lot!!!