Вопрос

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

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

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

Это было полезно?

Решение

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

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

private static final MethodObject methodObject = new MethodObject();

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

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

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

Другие советы

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

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

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

  1. Реорганизуйте класс, чтобы он был классом экземпляра и реализовывал интерфейс.

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

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

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

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

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

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

Итак, допустим, ваш код выглядит следующим образом:

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

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

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

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

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

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 с каким-то издевательским интерфейсом.Преимущество заключается в том, что вам не нужно менять клиентов вашего статического класса.Недостатком является то, что у вас, вероятно, будет немного дублированный код, потому что вам придется повторять методы статического класса и его реализацию.Но иногда статические методы могут использовать другой интерфейс, который обеспечивает базовую функциональность.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top