Подтвердить что ты не робот

Как насмехаться со статическими методами?

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

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

Какой лучший способ? Должен ли я просто использовать методы экземпляра (что кажется неправильным) или есть другое решение?

4b9b3361

Ответ 1

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

то есть. в вашем классе со статическим методом:

private static final MethodObject methodObject = new MethodObject();

public static void doSomething(){
    methodObject.doSomething();
}

и ваш объект метода может быть очень простым, легко протестированным:

public class MethodObject {
    public void doSomething() {
        // do your thang
    }
}

Ответ 2

Я нашел блог через google с некоторыми замечательными примерами о том, как это сделать:

  • Класс refactor должен быть классом экземпляра и реализовывать интерфейс.

    Вы уже заявили, что не хотите этого делать.

  • Используйте класс экземпляра оболочки с делегатами для членов статических классов.

    Выполняя это, вы можете имитировать статический интерфейс через делегатов.

  • Используйте класс экземпляра-оболочки с защищенными членами, которые вызывают статический класс

    Это, пожалуй, самый простой способ издеваться/управлять без рефакторинга, поскольку он может просто наследоваться и расширяться.

Ответ 3

Да, вы используете методы экземпляра. Статические методы в основном говорят: "Существует один способ выполнить эту функцию - это не полиморфно". Издевательский полагается на полиморфизм.

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

Ответ 4

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

Итак, скажем, ваш код выглядит так:

public object GetData()
{
 object obj1 = GetDataFromWherever();
 object obj2 = TransformData(obj1);
 return obj2;
} 
private static object TransformData(object obj)
{
//Do whatever
}

Вам не нужно писать тест против метода TransformData (и вы не можете). Вместо этого напишите тест для метода GetData, который проверяет работу, выполненную в TransformData.

Ответ 5

Использовать методы экземпляра, где это возможно.

Использовать общедоступный static Func [T, U] (ссылки на статические функции, которые можно заменить макетными функциями), где методы экземпляра невозможны.

Ответ 6

Простое решение состоит в том, чтобы позволить изменять реализацию статического класса через сеттер:

class ClassWithStatics {

  private IClassWithStaticsImpl implementation = new DefaultClassWithStaticsImpl();

  // Should only be invoked for testing purposes
  public static void overrideImplementation(IClassWithStaticsImpl implementation) {
     ClassWithStatics.implementation = implementation;
  }

  public static Foo someMethod() {
    return implementation.someMethod();
  }

}

Итак, при настройке ваших тестов вы вызываете overrideImplementation с помощью какого-то издевавшегося интерфейса. Преимущество в том, что вам не нужно менять клиентов своего статического класса. Недостатком является то, что у вас, вероятно, будет небольшой дублированный код, потому что вам придется повторять методы статического класса и его реализации. Но иногда статические методы могут использовать интерфейс ligther, который обеспечивает базовую функциональность.

Ответ 7

Проблема заключается в том, что вы используете сторонний код и вызывается из одного из ваших методов. То, что мы закончили, - это обернуть его в объект и вызвать его с помощью dep inj, а затем ваш unit test может издеваться над сторонним статическим методом, вызывая с ним установщик.