Как проверить функцию, которая вызывает другую функцию void из нее со статическим значением в качестве аргумента, используя mockito - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть класс A как

Class A{
 private static final String ANON_DIR             = "/webapps/worldlingo/data/anonymizer/";
 private static final String NO_ANON             = "noanonymize";

  public String first(String text, String srclang, Map dictTokens) {
      Set<String> noAnonymize = new HashSet<String>();
      second(noAnonymize,ANON_DIR + NO_ANON, "tmpLang","name");

      String value;
      if(noAnonymize.contains("test")){
      value = word;
      }
      else {
         value = "test";
        }

    return value;
}

, где ANON_DIR и NO_ANON - конечное статическое значение.Этот класс имеет функцию first и функцию second. В первой функции есть вызывающий метод, который вызывает вторую функцию.Вторая функция - это функция void, которая принимает статические поля в качестве параметра.

Вторая функция - это просто функция чтения файла с путем, указанным в виде

private void second (Set<String> hashSet, String path, String lang , String type) {
    FileReader fr = null;
    BufferedReader br = null;

    try {
      fr = new FileReader(path);
      br = new BufferedReader(fr);
      String Line;
      while ((Line = br.readLine()) != null) {
        hashSet.add(Line);
      }
    } catch (IOException e) {
      log.error("Anonymizer: Unable to load file.", e);

    } finally {
      try {
        if (fr != null) {
          fr.close();
        }
        if (br != null) {
          br.close();
        }
      } catch (IOException e) {
        log.error("Anonymizer : An error occured while closing a resource.", e);
      }
    }
  }

  } 

Теперь я пытаюсь сначала протестировать функцию с помощью mockito.Я пытаюсь изменить статический параметр и отправить эти измененные статические параметры как

public void testfirst() throws Exception {
    A anon = new A();


    Field ANON_DIR = A.class.getDeclaredField("ANON_DIR");
    ANON_DIR.setAccessible(true);

    //java relection to change private static final field
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(ANON_DIR, ANON_DIR.getModifiers() & ~Modifier.FINAL);
    ANON_DIR.set(null,"test");

    Field NO_ANON = A.class.getDeclaredField("NO_ANON");
    NO_ANON.setAccessible(true);

    Field modifiersField1 = Field.class.getDeclaredField("modifiers");
    modifiersField1.setAccessible(true);
    modifiersField1.setInt(NO_ANON, NO_ANON.getModifiers() & ~Modifier.FINAL);
    NO_ANON.set(null,"/noanonymize");


    Method anonymizeNames = anon.getClass().getDeclaredMethod("first", String.class, String.class , Map.class);
    String srcLang = "MSFT_EN";
    Map mapTokens = new HashMap();
    String result = (String) anonymizeNames.invoke(anon,"I am David",srcLang,mapTokens);


  }

ПРОБЛЕМА: Здесь я могу изменить закрытое конечное статическое поле ANON_DIR и NO_ANON, используя отражение Java, но измененное поле не отправляется ввторая функция.Вторая функция, вызываемая из первой функции, принимает исходное значение вместо измененного значения.то есть, когда второй вызывается, ANON_DIR имеет значение "/ webapps / worldlingo / data / anonymizer /" вместо "test".

Поскольку я изменил значение ANON_DIR на «test», я хочу, чтобы это же «test» значение было передано второй функции.Как я могу добиться этого для проверки второго пустого метода.

1 Ответ

0 голосов
/ 31 декабря 2018

Проблема здесь заключается в нарушении принципа Разделение интересов .

Ваш тестируемый код (вырезать) делает слишком много, и, таким образом, у вас есть трудныйвремя найти швы для замены зависимостей.

Также существует недопонимание цели юнит-тестов.Вы не тестируете код, вы тестируете общедоступное наблюдаемое поведение , которое представляет собой любое возвращаемое значение и связь с зависимостями (но не обязательно общедоступными методами) .

Поэтому я предлагаю переместить метод second() в новый собственный класс.Разрез получает экземпляр этого нового класса, переданного как параметр конструктора .Тогда реальную зависимость легко заменить на макет этого нового класса в вашем тесте.

С другой стороны, вы можете просто отказаться от своего плохого дизайна, используя PowerMock ...

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