Как я могу протестировать последние и статические методы служебного проекта?

У меня был тот же вопрос, и это действительно запутанно, вы должны учитывать, что переопределение и новые ключевые слова работают только с объектами базового класса типа и значением производного класса. В этом случае вы увидите эффект переопределения и новый: Итак, если у вас есть class A и B, B наследуется от A, вы создаете экземпляр объекта следующим образом:

A a = new B();

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

https://msdn.microsoft.com/EN-US/library/ms173153%28v=VS.140,d=hv.2% 29.aspx е = 255 & амп;? MSPPError = -2147217396

24
задан talk to frank 18 August 2009 в 11:56
поделиться

6 ответов

Вместо этого вы можете написать следующее:

$qry = "SELECT * FROM mytable where userid='";
$qry.= mysql_real_escape_string($_GET['userid'])."' AND category='";
$qry.= mysql_real_escape_string($_GET['category'])."' ORDER BY id DESC";

Но использовать подготовленные операторы лучше использовать универсальную библиотеку,

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

Вот пример теста, имитирующий статический конечный метод в этом примере показано, как имитировать и некоторые другие типы:

@Test
public void testMockStaticFinal() throws Exception {
    mockStatic(StaticService.class);
    String expected = "Hello altered World";
    expect(StaticService.sayFinal("hello")).andReturn("Hello altered World");
    replay(StaticService.class);

    String actual = StaticService.sayFinal("hello");

    verify(StaticService.class);
    assertEquals("Expected and actual did not match", expected, actual);

    // Singleton still be mocked by now.
    try {
        StaticService.sayFinal("world");
            fail("Should throw AssertionError!");
    } catch (AssertionError e) {
        assertEquals("\n  Unexpected method call sayFinal(\"world\"):", 
            e.getMessage());
    }
}
28
ответ дан 28 November 2019 в 23:42
поделиться

JMockit позволяет вам высмеивать статические методы и конечные классы. Я предполагаю, что он использует некоторый classloadin-fu, хотя я действительно не изучал это.

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

3
ответ дан Rogério 28 November 2019 в 23:42
поделиться

Как уже отмечалось, можно использовать JMockit . Пример:

@Test
public void mockStaticAndFinalMethods(@Mocked LegacyService mock) {
    new Expectations() {{
        LegacyService.staticMethod("hello"); result = "Hello altered World";
    }};

    String actual = LegacyService.staticMethod("hello");
    new LegacyService().finalMethod(123, "test");

    assertEquals("Hello altered World", actual);

    new Verifications() {{
        mock.finalMethod(123, "test"); // verify this call occurred at least once
    }};
}
2
ответ дан 28 November 2019 в 23:42
поделиться

Если ваш метод, не подлежащий рефакторингу, использует что-то вроде JNDI для подключения к другой службе, я бы подумал о запуске службы JDNI и заполнении ее заглушками, которые вы контролируете. Это больно, но относительно просто. Это может означать настройку базы данных или прослушивателя JMS или чего-то еще, но должна быть облегченная реализация java, которую вы можете добавить в тесты.

1
ответ дан 28 November 2019 в 23:42
поделиться

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

-1
ответ дан 28 November 2019 в 23:42
поделиться

Как насчет уровня косвенного обращения / внедрения зависимостей?

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

public LegacyActions : ILegacyActions
{
  public void SomeMethod() { // delegates to final/static legacy utility method }
}

Для своих тестов вы можете создать имитацию этого интерфейса и избежать взаимодействия с устаревшей утилитой.

6
ответ дан 28 November 2019 в 23:42
поделиться
Другие вопросы по тегам:

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