使用构造函数的参数测试抽象类

时间:2016-10-07 00:18:21

标签: java mockito

我试图了解测试但我在测试抽象类时遇到了一些问题。我知道我可以创建一个继承自Dog的具体子类,比如ConcreteDog,但是如果我向Dog添加一个新的抽象方法,我将不得不向ConcreteDog添加一个空方法。我想这不会那么酷。

public abstract class Dog {
  private final int id;

  public Dog(int id) {
    this.id = id;
  }

  public int getId() {
    return id;
  }

  public abstract void makeSound();
}

...

public class DogTest {
  @Test
  public void testGetId() {
    int id = 42;

    // How to pass id to Dog constructor ?
    Dog dog = Mockito.mock(Dog.class, Mockito.CALL_REAL_METHODS);

    assertTrue(dog.getId() == id);
  }
}

我试图做的是以某种方式用构造函数调用Mock,比如

Mockito.mock(Dog(id).class, Mockito.CALL_REAL_METHODS);

我不知道simito是否可行,但有一种方法可以使用mockito或其他工具吗?

3 个答案:

答案 0 :(得分:3)

如果需要,可以使用反射设置字段,这基本上复制了构造函数如何设置成员字段。

Dog dog = Mockito.mock(Dog.class, Mockito.CALL_REAL_METHODS);
ReflectionTestUtils.setField(dog , "id", 42);

答案 1 :(得分:2)

您可以这样做:

Mockito.mock(Dog.class, Mockito.withSettings()
        .useConstructor(999)
        .defaultAnswer(Mockito.CALLS_REAL_METHODS)
);

其中999-是id参数的任何整数。因此,您不必再继承抽象类。您还可以根据构造函数的需要传递尽可能多的参数,例如:

.useConstructor(new Object(), "my string", 5.5, null)

答案 2 :(得分:1)

由于Dog是一个抽象类,我建议先创建一个子类。

class TestDog extends Dog {
...
}

然后,您需要创建TestDog的模拟并定义其行为。然后,当您创建TestDog.class的实例时,返回TestDog的模拟,例如......

TestDog mock_dog = mock(TestDog.class); 
when(mock_dog.getId()).thenReturn(99);
whenNew(TestDog.class).withArguments(anyInt()).thenReturn(mock_dog);

尝试一下,让我知道