jUnit,模拟。如何确保抽象class中的方法(模板方法)调用抽象钩子方法?
jUnit, Mockito. How to ensure a method in abstract class (a templae method) invokes the abstract hook method?
我来了:
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;
}
...
}
问题是我如何对 updateWith(...)
进行单元测试以确保它明确地调用在后代中实现的抽象 doUpdateWith(...)
(是的,当然,如果我通过了所有检查)?
就是你们!
创建一个虚拟子class
class ConcreteEntity extends IdentifiedEntity<ConcreteEntity> {
@Override
void doUpdateWith(ConcreteEntity that) {
}
}
然后像这样测试:
@Test
public void test() throws Exception {
ConcreteEntity e = Mockito.spy(new ConcreteEntity());
e.updateWith(e);
Mockito.verify(e).doUpdateWith(e);
}
不过这样的考试很特别。它不允许您更改方法的实现。
在@CoronA的帮助下,我找到了答案。这是:
@Test
public void updateWith() {
User user = this.user.clone().setId(100);
User mock = Mockito.spy(user);
mock.updateWith(user);
Mockito.verify(mock).doUpdateWith(user);
}
非常感谢你们!!!
我来了:
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;
}
...
}
问题是我如何对 updateWith(...)
进行单元测试以确保它明确地调用在后代中实现的抽象 doUpdateWith(...)
(是的,当然,如果我通过了所有检查)?
就是你们!
创建一个虚拟子class
class ConcreteEntity extends IdentifiedEntity<ConcreteEntity> {
@Override
void doUpdateWith(ConcreteEntity that) {
}
}
然后像这样测试:
@Test
public void test() throws Exception {
ConcreteEntity e = Mockito.spy(new ConcreteEntity());
e.updateWith(e);
Mockito.verify(e).doUpdateWith(e);
}
不过这样的考试很特别。它不允许您更改方法的实现。
在@CoronA的帮助下,我找到了答案。这是:
@Test
public void updateWith() {
User user = this.user.clone().setId(100);
User mock = Mockito.spy(user);
mock.updateWith(user);
Mockito.verify(mock).doUpdateWith(user);
}
非常感谢你们!!!