2013-11-16 6 views
3

У меня есть сценарий, как этотКак поиздеваться локальные переменные с помощью Mockito или powermock

InputStreamReader reader = new InputStreamReader(getFileAsStream(resourceResolver, iconpath)); 
       BufferedReader bReader = new BufferedReader(reader); 

я издевался до этого момента

getFileAsStream(resourceResolver, iconpath) 

Теперь я получаю один читатель

BufferedReader bReader = new BufferedReader(reader); 

но когда я выполняю эту строку, я получаю нулевое значение и не могу двигаться вперед

while ((iconEntry = bReader.readLine()) != null) 

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

Код испытания

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ FrameworkUtil.class, LoggerFactory.class }) 
public class IconPreviewServletTest { 
    private IconPreviewServlet iconPreviewServlet; 
    private SlingHttpServletRequest request; 
    private SlingHttpServletResponse response; 
    private Bundle bundle; 
    private BundleContext bundleContext; 
    private ServiceReference factoryRef; 
    private CommonService resolverFactory; 
    private PrintWriter out; 
    private ResourceResolver resourceResolver; 
    private Resource resource; 
    private Node node; 
    private Node jcrContent; 
    private javax.jcr.Property property; 
    private Binary binary; 
    private InputStream stream; 
    private InputStreamReader inputReader; 
    private BufferedReader reader; 

    @Before 
    public void setUp() throws IOException, PathNotFoundException, 
      RepositoryException { 
     init(); 
    } 

    private void init() throws IOException, PathNotFoundException, 
      RepositoryException { 

     request = mock(SlingHttpServletRequest.class); 
     response = mock(SlingHttpServletResponse.class); 
     bundleContext = mock(BundleContext.class); 
     factoryRef = mock(ServiceReference.class); 
     resolverFactory = mock(CommonService.class); 
     out = mock(PrintWriter.class); 
     resourceResolver = mock(ResourceResolver.class); 
     resource = mock(Resource.class); 
     node = mock(Node.class); 
     jcrContent = mock(Node.class); 
     property = mock(Property.class); 
     binary = mock(Binary.class); 
     stream=IOUtils.toInputStream("some test data for my input stream"); 



     reader = mock(BufferedReader.class); 

     inputReader=mock(InputStreamReader.class); 

     bundle = mock(Bundle.class); 
     mockStatic(FrameworkUtil.class); 
     mockStatic(LoggerFactory.class); 

     Logger log = mock(Logger.class); 

     when(LoggerFactory.getLogger(IconPreviewServlet.class)).thenReturn(log); 
     when(FrameworkUtil.getBundle(CommonService.class)).thenReturn(bundle); 
     when(bundle.getBundleContext()).thenReturn(bundleContext); 
     when(bundleContext.getServiceReference(CommonService.class.getName())) 
       .thenReturn(factoryRef); 
     when(bundleContext.getService(factoryRef)).thenReturn(resolverFactory); 
     when(request.getParameter("category")).thenReturn("category"); 
     when(request.getParameter("query")).thenReturn("query"); 
     when(response.getWriter()).thenReturn(out); 
     when(request.getResourceResolver()).thenReturn(resourceResolver); 
     when(
       resourceResolver 
         .getResource("/etc/designs/resmed/icons/category/icons.txt")) 
       .thenReturn(resource); 
     when(resource.adaptTo(Node.class)).thenReturn(node); 
     when(node.getNode("jcr:content")).thenReturn(jcrContent); 
     when(jcrContent.getProperty("jcr:data")).thenReturn(property); 
     when(property.getBinary()).thenReturn(binary); 
     when(binary.getStream()).thenReturn(stream); 

    } 
+0

Вы могли бы показать тестовый код? –

+0

@TienNguyen тестовый код добавлен – ankit

ответ

8

Чтобы выполнить эту работу, вам необходимо использовать Powermockito для перехвата вызовов конструктора (новый InputStreamReader (...), новый BufferedReader (...)), чтобы ваши mocks возвращались. Ниже приведен пример. В вашем случае достаточно перехватить новый вызов BufferedReader.

Предположим Ниже приведен код, который вы хотите проверить:

package test; 

import java.io.*; 

public class SUT { 

    public String doSomething() throws IOException { 
     InputStreamReader reader = 
       new InputStreamReader(getFileAsStream(null, null)); 
     BufferedReader bReader = 
       new BufferedReader(reader); 

     return bReader.readLine(); 
    } 

    private InputStream getFileAsStream(Object resourceResolver, Object iconPath) 
      throws FileNotFoundException { 
     return new ByteArrayInputStream("".getBytes()); 
    } 
} 

Следующий тестовый код является примером того, как перехватить конструктор вызывает:

package test; 

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; 

import java.io.BufferedReader; 
import java.io.InputStreamReader; 

import static org.junit.Assert.assertEquals; 
import static org.powermock.api.mockito.PowerMockito.doReturn; 
import static org.powermock.api.mockito.PowerMockito.mock; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ SUT.class }) 
public class SUTTest { 

    @Test 
    public void doSomethingReturnsValueFromBufferedReader() throws Exception { 
     // Arrange 
     SUT sut = new SUT(); 
     InputStreamReader inputStreamReaderMock = mock(InputStreamReader.class); 
     BufferedReader bufferedReaderMock = mock(BufferedReader.class); 

     // Set your mocks up to be returned when the new ...Reader calls 
     // are executed in sut.doSomething() 
     PowerMockito.whenNew(InputStreamReader.class). 
        withAnyArguments().thenReturn(inputStreamReaderMock); 
     PowerMockito.whenNew(BufferedReader.class). 
        withArguments(inputStreamReaderMock). 
        thenReturn(bufferedReaderMock); 

     // Set the value you want bReader.readLine() to return 
     // when sut.doSomething() executes 
     final String bufferedReaderReturnValue = "myValue"; 
     doReturn(bufferedReaderReturnValue).when(bufferedReaderMock).readLine(); 

     // Act 
     String result = sut.doSomething(); 

     // Assert 
     assertEquals(bufferedReaderReturnValue, result); 
    } 
} 

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

Высокое количество насмешек, вероятно, указывает на то, что дизайн кода, который вы тестируете, нуждается в некоторой работе, чтобы улучшить тестируемость. Если вы не можете коснуться кода, то вы не можете - но попробуйте сделать ваш тест более читабельным и интуитивно понятным («Когда этот метод вызывается, эта вещь должна произойти, потому что ...»).

1

, чтобы сделать эту линию работы:

while ((iconEntry = bReader.readLine()) != null) 

вы должны определите, сколько строк вы хотите прочитать, и добавьте это в свой тестовый код:

when(bReader.readLine()).thenReturn("line number one").thenReturn("line number two"); 
+0

в моем случае bReader - это оригинальный объект, так как я могу позвонить, когда на нем. Если я попытаюсь сделать это, я получаю исключение. Говоря, что вы звоните, когда на не издевающемся объекте – ankit

+0

вы также должны mock bReader, но вы уже положили его на свой тестовый код: «reader = mock (BufferedReader.class);» поэтому просто используйте его для вызова функции readLine() –

Смежные вопросы