Как передать автоматически проводные зависимости как ложные во время модульного тестирования класса, в котором есть конструкторы с аргументами - PullRequest
2 голосов
/ 14 июня 2019

Я пытаюсь провести модульное тестирование двух отдельных классов, конструктор одного является конструктором по умолчанию, а конструктор другого - конструктором, имеющим несколько аргументов. Оба класса имеют компонент с автопроводкой, скажем,

class A {
  @Autowired
  private SomeClass someClass;
}
class B {
  @Autowired
  private SomeClass someClass;

  public B(int a, String b) {
    //method implementation
  }
}

Я пытаюсь провести модульное тестирование этих двух классов и для первого, если я создаю объект класса, используя

def mockedSomeClass = Mock(SomeClass)
def a = new A(someClass:mockedSomeClass)

работает нормально.

Но для второго класса я попытался передать аргументы конструктора и зависимости, необходимые через различные синтаксисы

как

def mockedSomeClass = Mock(SomeClass)
def b = new B(10, "g", someClass:mockedSomeClass)

и

def b = new B(someClass:mockedSomeClass, 10, "g")

и

def b = new B(10, "g")(someClass:mockedSomeClass)

Все это было методом проб и ошибок, поскольку я не мог найти никакой документации, подобной этому конкретному случаю.

Любая помощь в том, как правильно это сделать, будет высоко оценена

Заранее спасибо

1 Ответ

1 голос
/ 14 июня 2019

В классе A вызов конструктора как этот

new A(someClass:mockedSomeClass)

работает нормально, потому что в groovy конструктор по умолчанию, который генерируется неявно, поддерживает установку значения любого поля с помощью , передавая именованный параметр , который поддерживается только в конструкторе по умолчанию. У вас было одно поле (someClass), которое вы прошли через конструктор, и все было в порядке.

Однако в классе B у вас есть явный конструктор с двумя аргументами. Обратите внимание, что вы можете вызывать этот конструктор только с этими двумя указанными аргументами (то есть int a, String b), так как он явно определен таким образом. Помните, что это не конструктор по умолчанию, как в классе A, поэтому он не поддерживает автоматическую установку поля путем передачи именованного параметра.

Короче говоря, чтобы это работало, вы должны явно указать и третий аргумент:

class B{

@Autowired
private SomeClass someClass;

public B(int a,String b, SomeClass someClass)
{
    //method implementation
    this.someClass = someClass;
}

И тогда вы можете назвать это так:

def b=new B(10, "g", mockedSomeClass)

Альтернативный подход :

Я бы предпочел подход сверху, так как он немного чище. Причина в том, что лучше иметь все обязательные зависимости в конструкторе, чтобы избежать путаницы.

Однако, если по какой-то причине вы не можете изменить исходный код Java, вы также можете решить эту проблему, создав объект следующим образом:

def b=new B(10, "g")
b.someClass = mockedSomeClass

В приведенном выше примере мы сначала создаем объект, вызывая явный конструктор класса B, который принимает 2 параметра. Затем мы устанавливаем поле someClass (это похоже на назначение частного поля вручную, но на самом деле мы устанавливаем его через установщик, который генерируется автоматически в groovy, о неявных получателях и установщиках можно прочитать здесь: http://groovy -lang.org / style-guide.html # _getters_and_setters ).

...