Возможно ли это в Mockito: когда (SomeClass.getIntance ()). ThenReturn (myMock)? - PullRequest
1 голос
/ 19 апреля 2011

Я работаю с устаревшим кодом, где мне нужно реализовать новый обработчик. И в этом обработчике есть объект, который, к сожалению, инициализируется платформой, используя некий жестко закодированный файл свойств, например:

// new code
public class NewHandler extends RootHandler {
  Util util = Util.getInstance(); // !!!Problem: throws NPE in unit-testing env

  // defined in the legacy framework, can't change its signature
  @Override
  public void doSth() {

  }
}

// legacy code
public class Util {
    static public synchronized Util getInstance() { 
        if (_instance == null) {
            _instance = new Util();
        }
        return _instance;
    }

    private Util() {
    MyObj obj = LegacyCode.load("myConfig.cfg"); // !!!Problem: throws NPE in unit-testing env
    ...

}
}

Теперь проблема:
в Util() он всегда загружает файл конфигурации из фиксированного местоположения, поэтому он всегда выдает NPE, когда я запускаю свои модульные тесты, поскольку в пути к классам модульного теста нет «myConfig.cfg».

Один из обходных путей - извлечь бизнес-логику в отдельный метод, передав объект Util, чтобы я мог передавать фиктивные объекты во время тестов:

// new code
public class NewHandler extends RootHandler {
  Util util = null;

  // defined in the legacy framework, can't change its signature
  @Override
  public void handle() {
    Util util = util.getInstance();
    doHandle(util);
  }

  public void doHandle(Util util) {
    ...
  }
}

// legacy code
public class Util {
  ...
}

Мой вопрос :
Есть ли другой способ обойти эту проблему, не добавляя метод doHandle ()? Я попробовал следующий код, используя Mockito:

Util myUtil = mock(Util.class);
when(Util.getInstance()).thenReturn(myUtil);

но это не сработало, Util.getInstance () не был заменен на myUtil.

есть мысли?

ОБНОВЛЕНИЕ : Все становится немного грязно, так как я обнаружил, что Util.getInstance () вызывается повсеместно в устаревшей базе кода. Поэтому, даже если у меня есть смоделированный Util в моем новом коде (как было описано Стасом ниже), все равно будет происходить сбой при вызове Util.getInstance () в другом месте.
Очевидно, что я не мог добавить новые конструкторы для каждого отдельного класса в устаревшем коде, который вызывает Util.getInstance ().


По этой причине я спрашиваю: «возможно ли иметь что-то в Mockito, например when (Sth.getInstance ()). ThenReturn (myMock)»
если да, все вызовы Util.getInstance () могут быть поддельными и больше не вызовут проблем.
Хм .... Есть идеи?

*********************************************** ************************
РЕШЕНИЕ : Я думаю, что решение в моем случае PowerMock

1 Ответ

1 голос
/ 19 апреля 2011

Вы должны попробовать smt как

 public class NewHandler extends RootHandler {
     Util util;
     //Pass instance
     NewHandler(Util util) {this.util = util;}
 }

Чем вы сможете использовать new NewHandler(Util.getInstance()) или new NewHandler(mock(Util.class)) в своих тестах.

PS Для получения дополнительной информации вы можете прочитать о Сервисный локатор и DI

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...