Как дразнить Строку с помощью mockito?

Используйте его каждый раз, когда Вы переопределяете метод для двух преимуществ. Сделайте это так, чтобы можно было использовать в своих интересах проверку компилятора, чтобы удостовериться, что Вы на самом деле переопределяете метод, когда Вы думаете, что Вы. Таким образом, если Вы делаете частую ошибку орфографической ошибки имени метода или не правильно соответствия параметрам, Вас предупредят, что Вы, которых на самом деле не переопределяет метод, поскольку Вы думаете, что это делает. Во-вторых, это делает Ваш код легче понять, потому что более очевидно, когда методы перезаписываются.

Кроме того, в Java 1.6 можно использовать его для маркировки, когда метод реализует интерфейс для тех же преимуществ. Я думаю, что было бы лучше иметь отдельную аннотацию (как @Implements), но это лучше чем ничего.

38
задан ROMANIA_engineer 14 May 2015 в 11:13
поделиться

11 ответов

Проблема в том, что класс String в Java помечен как final, поэтому вы не можете имитировать использование традиционных фреймворков имитации. Согласно Mockito FAQ , это тоже ограничение этой структуры.

39
ответ дан 27 November 2019 в 03:21
поделиться

Вы пытались передать недопустимое имя charsetName в getBytes (String)?

Вы могли бы реализовать вспомогательный метод для получения charsetName и переопределить этот метод в вашем тесте на бессмысленное значение.

1
ответ дан 27 November 2019 в 03:21
поделиться

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

Что это за заданная цель покрытия? Некоторые люди скажут, что съемка для 100% охвата не всегда хорошая идея .

Кроме того, это не способ проверить, была ли задействована блокировка захвата. Правильный способ - написать метод, который вызывает возникновение исключения, и сделать наблюдение за выбросом исключения критерием успеха. Вы делаете это с помощью аннотации JUnit @Test, добавляя «ожидаемое» значение:

@Test(expected=IndexOutOfBoundsException.class) public void outOfBounds() {
   new ArrayList<Object>().get(1);
}
1
ответ дан 27 November 2019 в 03:21
поделиться

Мокито не может издеваться над выпускными классами. JMock в сочетании с библиотекой от JDave может. Вот инструкции .

JMock не делает ничего особенного для финальных классов, кроме как полагаться на библиотеку JDave, чтобы отменить финализацию всего в JVM, поэтому вы можете поэкспериментировать с использованием нефинализатора JDave и посмотреть, сможет ли Mockito затем издевайтесь над этим.

3
ответ дан 27 November 2019 в 03:21
поделиться

Судя по документации, JDave не может удалить модификаторы final из классов, загруженных загрузчиком классов начальной загрузки. Сюда входят все классы JRE (из java.lang, java.util и т. Д.).

Инструмент, позволяющий имитировать что угодно, - это JMockit .

С JMockit ваш тест может быть написан как:

import java.io.*;
import org.junit.*;
import mockit.*;

public final class ATest
{
   @Test(expected = UnsupportedOperationException.class)
   public void test() throws Exception
   {
      new Expectations()
      {
         @Mocked("getBytes")
         String aString;

         {
            aString.getBytes(anyString);
            result = new UnsupportedEncodingException("Parsing error.");
         }
      };

      A.f("test");
   }
}

при условии, что полный класс «A»:

import java.io.*;

public final class A
{
   public static String f(String str)
   {
      try {
         return new String(str.getBytes("UTF-8"));
      }
      catch (UnsupportedEncodingException e) {
         throw new UnsupportedOperationException(e);
      }
   }
}

Я действительно выполнил этот тест на своей машине. (Обратите внимание, что я заключил исходное проверенное исключение в исключение времени выполнения.)

Я использовал частичное высмеивание через @Mocked ("getBytes") , чтобы JMockit не издевался над всем в java.lang. String class (только представьте, к чему это может привести)

Теперь этот тест действительно не нужен, потому что «UTF-8» - это стандартная кодировка, которая должна поддерживаться во всех JRE. Следовательно, в производственной среде блок перехвата никогда не будет выполнен.

Тем не менее, «потребность» или желание покрыть блок перехвата остается в силе. Итак, как избавиться от теста без снижения процента покрытия? Вот моя идея: вставить строку с assert false; в качестве первого оператора внутри блока catch, и пусть инструмент Code Coverage игнорирует весь блок catch при сообщении о мерах покрытия. Это один из моих «TODO-пунктов» для JMockit Coverage. 8 ^)

и пусть инструмент Code Coverage игнорирует весь блок catch при сообщении о мерах покрытия. Это один из моих «TODO-пунктов» для JMockit Coverage. 8 ^)

и пусть инструмент Code Coverage игнорирует весь блок catch при сообщении о мерах покрытия. Это один из моих «TODO-пунктов» для JMockit Coverage. 8 ^)

5
ответ дан 27 November 2019 в 03:21
поделиться

Как насчет того, чтобы просто создать String с неправильным именем кодировки? См.

public String(byte bytes[], int offset, int length, String charsetName)

Mocking String почти наверняка плохая идея.

13
ответ дан 27 November 2019 в 03:21
поделиться

Как указали другие, вы не можете использовать Mockito для имитации последнего класса. Однако более важным моментом является то, что тест не особенно полезен, потому что он просто демонстрирует, что String.getBytes () может вызвать исключение, что, очевидно, и может. Если вы серьезно относитесь к тестированию этой функции, я думаю, вы могли бы добавить параметр для кодировки в f () и отправить неверное значение в тест.

Кроме того, вы вызываете ту же проблему для вызывающий Af () , потому что A является окончательным, а f () статическим.

Эта статья может быть полезна для того, чтобы убедить ваших коллег быть менее догматические о 100% покрытии кода: Как потерпеть неудачу при 100% покрытии тестами .

7
ответ дан 27 November 2019 в 03:21
поделиться

Вы будете тестировать код, который никогда не может быть выполнен. Поддержка UTF-8 требуется на каждой виртуальной машине Java, см. http://java.sun.com/javase/6/docs/api/java/nio/charset/Charset.html

3
ответ дан 27 November 2019 в 03:21
поделиться

Вы также можете использовать расширение PowerMock Mockito для имитации конечных классов / методов даже в системных классах, таких как String. Однако я бы также посоветовал не имитировать getBytes в этом случае и лучше попытаться настроить ваше ожидание так, чтобы вместо этого использовалась настоящая String, заполненная ожидаемыми данными.

3
ответ дан 27 November 2019 в 03:21
поделиться

Если все, что вы собираетесь делать в блоке catch, - это бросать исключение во время выполнения, то вы можете сэкономить на вводе текста, просто используя объект Charset для указания имени набора символов.

public final class A{
    public static String f(String str){
        return new String(str.getBytes(Charset.forName("UTF-8")));
    }
}

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

13
ответ дан 27 November 2019 в 03:21
поделиться

Возможно, вместо A.f(String) следует использовать A.f(CharSequence). Вы можете издеваться над CharSequence.

1
ответ дан 27 November 2019 в 03:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: