yes Возможно. Тип возврата может быть другим, только если тип возвращаемого типа родительского класса - это супер тип метода возвращаемого типа дочернего класса .. означает
class ParentClass {
public Circle() method1() {
return new Cirlce();
}
}
class ChildClass extends ParentClass {
public Square method1() {
return new Square();
}
}
Class Cirlce {
}
class Square extends Circle {
}
---
Если это другое значение возвращаемый тип может быть разрешен ...
Я использовал бы шаблон объекта метода. Имейте статический экземпляр этого и назовите его в статическом методе. Должно быть возможно разделить на подклассы для тестирования, в зависимости от Вашей платформы насмешки.
т.е. в Вашем классе со статическим методом имейте:
private static final MethodObject methodObject = new MethodObject();
public static void doSomething(){
methodObject.doSomething();
}
и Ваш объект метода может быть очень простое, легко протестированный:
public class MethodObject {
public void doSomething() {
// do your thang
}
}
Да, Вы используете методы экземпляра. Статические методы в основном говорят, "Существует один способ выполнить эту функциональность - это не полиморфно". Насмешка полагается на полиморфизм.
Теперь, если Ваши статические методы логически не заботятся, о какой реализации Вы используете, они могли бы быть в состоянии взять интерфейсы в качестве параметров, или возможно работать, не взаимодействуя с состоянием вообще - но иначе необходимо использовать экземпляры (и вероятно внедрение зависимости для проводного соединения всего вместе).
Я нашел блог через Google с некоторыми яркими примерами о том, как сделать это:
Осуществляют рефакторинг класс, чтобы быть классом экземпляра и реализовать интерфейс.
Вы уже заявили, что не хотите делать это.
Использование класс экземпляра обертки с делегатами к статическим участникам классов
Выполнение этого можно моделировать статический интерфейс через делегатов.
Использование класс экземпляра обертки с защищенными участниками, которые называют статический класс
, который Это является, вероятно, самым легким дразнить/управлять, не осуществляя рефакторинг, поскольку это может просто быть наследовано от и расширено.
Используйте методы экземпляра, если это возможно.
общественность Использования статический Func [T, U] (статические ссылки на функцию, которыми можно заменить ложные функции), где методы экземпляра не возможны.
Простое решение должно позволить изменять реализацию статического класса через метод set:
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
с некоторым дразнившим интерфейсом. Преимущество - то, что Вы не должны изменять клиенты своего статического класса. Оборотная сторона - то, что Вы, вероятно, немного копируете код, потому что необходимо будет повторить методы статического класса, и это - реализация. Но несколько раз статические методы могут использовать более легкий интерфейс, которые обеспечивают основу funcionality.
Вы могли бы пытаться протестировать в слишком глубокой начальной точке. Тест не должен быть создан для тестирования каждого метода индивидуально; закрытые и статические методы должны быть протестированы путем вызова открытых методов, которые тогда называют частные и статические в свою очередь.
Так позволяет, говорят, что Ваш код похож на это:
public object GetData()
{
object obj1 = GetDataFromWherever();
object obj2 = TransformData(obj1);
return obj2;
}
private static object TransformData(object obj)
{
//Do whatever
}
Вы не должны писать тест против метода TransformData (и Вы не можете). Вместо этого запишите тест для метода GetData, который тестирует работу, сделанную в TransformData.
The problem you have is when you're using 3rd party code and it's called from one of your methods. What we ended up doing is wrapping it in an object, and calling passing it in with dep inj, and then your unit test can mock 3rd party static method call the setter with it.