2013-03-15 2 views
3

Пожалуйста, со мной, как я новичок в мире TDD.TDD: как издеваться над статическим методом в Java?

У меня есть класс FileGenerator, и я пишу тест на generateFile() метод, который необходимо сделать следующее:

1) он должен вызвать статический метод getBlockImpl(FileTypeEnum) на BlockAbstractFactory

2) он должен заполнить переменную blockList из метода подкласса getBlocks()

3) он должен вызвать статический метод createFile от конечного вспомогательного класса FileHelper передавая параметр типа String

4) он должен вызвать метод выполнения каждого BlockController в Blocklist

До сих пор, у меня есть этот пустой метод:

public class FileGenerator { 
    // private fields with Getters and Setters 

    public void generateBlocks() { 
    } 
} 

Я использую JUnit, Mockito издеваться объектов и я вы пытались использовать PowerMockito, чтобы издеваться над статическими и конечными классами (которые Mockito не делает).

Моя проблема: мой первый тест (вызов метода getBlockList() от BlockAbstractFactory) проходит, хотя в generateBlocks() нет реализации. Я применил статический метод в BlockAbstractFactory (возвращая значение null, пока), чтобы избежать синтаксических ошибок Eclipse.

Как проверить, вызван ли статический метод в пределах fileGerator.generateBlocks()?

Вот мой тест класса, до сих пор:

@RunWith(PowerMockRunner.class) 
public class testFileGenerator { 
    FileGenerator fileGenerator = new FileGenerator(); 

    @Test 
    public void shouldCallGetBlockList() { 
      fileGenerator.setFileType(FileTypeEnum.SPED_FISCAL); 

      fileGenerator.generateBlocks(); 

      PowerMockito.mockStatic(BlockAbstractFactory.class); 
      PowerMockito.verifyStatic(); 
      BlockAbstractFactory.getBlockImpl(fileGenerator.getFileType()); 
    } 
} 
+8

абстрактные методы не могут быть статичными – ArtB

+3

Самый простой ответ, если вы решили сделать TDD, пнуть привычку писать статические методы :) – Affe

+0

@ArtB это статический метод из Абстрактный класс, а не абстрактный статический метод. EDIT: просто увидел ошибку в моем вопросе. Исправлена. – Tarek

ответ

5

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

Я обнаружил, что вам нужно подготовить PowerMock, чтобы я знал, какие статические методы ему нужно подготовить, чтобы быть издеваемыми. Например:

@RunWith(PowerMockRunner.class) 
@PrepareForTest(BlockAbstractFactory.class) // <<=== Like that 
public class testFileGenerator { 
    // rest of you class 
} 

Here вы можете найти более подробную информацию.

Помогло ли это?

+0

Спасибо! Он работал, когда я добавил @PrepareForTest и когда мой тестовый класс расширил TestCase! Вот полное решение: '@RunWith (PowerMockRunner.class) @PrepareForTest (BlockAbstractFactory.class) общественного класса testFileGenerator расширяет TestCase { // тот же код, с @Before и @After предложение }' – Tarek

+0

@ user1042273 Эй, хороший! Напомните комментарий Аффе. Статические методы - это боль с TDD. Используйте их с осторожностью. Если вы добавляете состояние к статическим классам/общедоступным статическим методам, вам будет сложно использовать TDD. Вы доберетесь туда, и спасибо за этот вопрос, я никогда не слышал о насмешливой структуре, которая может обрабатывать статические классы :). Я подниму его. Приветствуйте и получайте удовольствие! – bas

+1

Еще одна проблема, которую следует учитывать, заключается в том, что издевательские статические методы требуют манипуляции с байт-кодом во время выполнения и имеют стоимость исполнения. Если вы только издеваетесь над одним или двумя статическими методами, вы можете быть в порядке, но если вы это часто делаете, вы можете действительно замедлить свои тесты. – bcarlso

0

Рабочий пример:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ClassStaticA.class, ClassStaticB.class}) 
public class ClassStaticMethodsTest { 

    @Test 
    public void testMockStaticMethod() { 
     PowerMock.mockStatic(ClassStaticA.class); 
     EasyMock.expect(ClassStaticA.getMessageStaticMethod()).andReturn("mocked message"); 
     PowerMock.replay(ClassStaticA.class); 
     assertEquals("mocked message", ClassStaticA.getMessageStaticMethod()); 
    }