2013-02-19 2 views
5

У меня есть следующий пример тестового блока, который пытается издеваться над java.nio.file.Files, но этот макет не работает, и код пытается удалить путь образца.Статический макет не работает

@Test 
    public void testPostVisitDirectory() throws Exception { 
     Path mockedPath = Paths.get("sample path"); 
     PowerMockito.mockStatic(Files.class); 
     PowerMockito.doNothing().when(Files.class, 
       PowerMockito.method(Files.class, "delete", Path.class)); 

     DeleteDirVisitor visitor = new DeleteDirVisitor(false); 
     Assert.assertEquals("The was a problem visiting the file", 
       FileVisitResult.CONTINUE, 
       visitor.postVisitDirectory(mockedPath, null)); 
    } 

Любая идея, что не так?

это содержание метода visitor.postVisitDirectory

[...] 
if (e == null) { 
      Files.delete(dir); 
      return FileVisitResult.CONTINUE; 
     } 
[...] 

Спасибо,

+0

КСТАТИ Я получаю NoSuchFileException. – Stainedart

ответ

4

Вы добавили

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Files.class) 

вашему JUnit тестовый класс, содержащий этот метод?

См. powermock docs, раздел «Написание тестов».

EDIT:

Хммм, похоже, что вы все делаете правильно. Вот что я бегу:

import java.io.IOException; 
import java.nio.file.FileVisitResult; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.nio.file.SimpleFileVisitor; 

import org.junit.Assert; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Files.class) 
public class TestVisitor { 
    public class PrintingVisitor extends SimpleFileVisitor<Path> { 
    @Override 
    public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException { 
     Files.delete(dir); 
     return FileVisitResult.CONTINUE; 
    } 
    } 

    @Test 
    public void testPostVisitDirectory() throws Exception { 
    final Path mockedPath = Paths.get("sample path"); 

    /* Mocking */ 
    PowerMockito.mockStatic(Files.class); 
    PowerMockito.doNothing().when(Files.class, PowerMockito.method(Files.class, "delete", Path.class)); 
    /* End Mocking */ 

    final PrintingVisitor visitor = new PrintingVisitor(); 
    Assert.assertEquals("The was a problem visiting the file", FileVisitResult.CONTINUE, visitor.postVisitDirectory(mockedPath, null)); 
    } 
} 

Если я закомментируйте раздел, обозначенный Дразнящий я получаю NoSuchFileException. Если я оставлю это, тест пройдет.

Возможно, после завершения полного примера, который вызывает ошибку?

+0

Да, это присутствует. В том же классе я на самом деле имеют заглушки '' 'PowerMockito.stub ( \t \t \t \t PowerMockito.method (Files.class "deleteIfExists", Path.class)) \t \t \t \t .toReturn (истина);' '', который работает – Stainedart

+0

, но поскольку delete возвращает void, я не могу использовать ту же технику :( – Stainedart

+0

Моя проблема может быть сложнее, чем я. Я успешно выполнил ваш фрагмент в отдельном классе, но он не работает в моем текущем классе. Может ли Mocking mess вещи на уровне тестового класса? – Stainedart

1

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

В приведенном выше примере класс, который был протестирован, уже находился в «prepareFor-Scope», потому что это был внутренний класс тестового класса.

Вы должны добавить классы к @PrepareForTest, которые вызывают статические методы ... и в моем случае это было недостаточно, потому что код, который обращался к Files.delete, находился внутри анонимного класса, который не может быть явно подготовлен.

Я назвал анонимный класс и добавить его в @PrepareForTest и все работало

+0

Я попытался добавить класс в @PrepareForTest, но затем столкнулся с ошибкой в ​​стеке из-за ошибки в последнем javassist: https://issues.jboss.org/browse/JASSIST-205 :-(. Класс файлов, но спасибо за подсказку! –

2

У меня была аналогичная проблема с использованием powermock 1.5.1 и класс файлов и подозреваю, что есть проблема статического насмешливый некоторые/все классы jdk1.7 , хотя я не знаю, почему. Я также проверил вариант javassist и в то время, когда он был последним (3.18.0-GA),

Я удалил свой класс под тест только в строку «Файлы», и он все еще не работал. Затем я решил попытаться высмеять еще один статический класс StringUtils.chop («string»); (commons-lang3), а затем мой силовой тест работал, и я смог заставить его генерировать исключение из mock.

Это доказало мне, что я сделал все по книге, и это статическое издевательство не работало над классом Files, но оно было сделано на StringUtils.

Кстати, я изменил оба метода: @PrepareForTest и PowerMockito.mockStatic() для ссылки на правильный класс.

В итоге я отказался от насмешливых Файлов. Просто хедз-ап на случай, если у кого-то другая проблема.

EDIT. Получил его работу: С тех пор я попробовал это снова, поскольку мне это нужно в другом проекте. Существует более новая версия PowerMock out (1.5.3), в которой используется обновленный javassist (3.18.1-GA), который исправляет ошибку, о которой я упоминал в своем ответе на другой комментарий.

я могу последовательно получить Осмеяние Files работать, добавив класс испытываемого к @PrepareForTest, а также Files теперь даже если классу тестируемые не подвергать статические методы. Мне не нужно было делать это раньше для других статических насмешек. Я не знаю, зачем это нужно или работает по-другому для Files.

Пример:

public class MyTestClass { 

    public void justToTestMocking(Path path) throws IOException { 
     if (!Files.exists(path)) { 
      throw new IllegalArgumentException("I know there is a deleteIfExists() but I am just testing mocking"); 
     } 
     Files.delete(path); 
    } 
} 

И тест ниже:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Files.class, MyTestClass.class}) 
public class MyTestClassTest { 

    @Before 
    public void setUp() { 
     mockStatic(Files.class); 

    }   

    @Test 
    public void justToTestMocking_WillDeletePath() throws IOException { 
     Path path = mock(Path.class); 
     MyTestClass test = new MyTestClass(); 

     when(Files.exists(path)).thenReturn(true); 

     test.justToTestMocking(path); 

     verifyStatic(); 
     Files.delete(path); 
    } 
}