2012-02-17 21 views
9

Tôi đang thử nghiệm luồng đầu ra trong java giống như dưới đây.Kiểm tra outputstream.write (<String>) mà không cần tạo một tệp

Writer outputStream = getOutputStream(fileName); 
    if(outputStream != null) { 
     try { 
      outputStream.write(inputText); 
     } 
     finally { 
      outputStream.close(); 
     } 
    } 
    else { 
     throw new IOException("Output stream is null"); 
    } 

Tôi viết một bài kiểm tra Mockito như sau

public void testFileWrite() throws IOException { 
    when(testObj.getOutputStream(outputFileNameValidValue)).thenReturn(outputStreamMock); 
    doNothing().when(outputStreamMock).write(Matchers.anyString()); 
    doNothing().when(bufferedReaderMock).close(); 

    testObj.write(outputFileNameValidValue, reveredFileInput); 

    verify(outputStreamMock).write(Matchers.anyString()); 
    verify(outputStreamMock).close(); 
} 

Vấn đề là khi bạn tạo OutputStreamWriter(new FileOutputStream(filename)) một tập tin vật lý trên đĩa được tạo ra.

Chúng tôi có thể kiểm tra Outputstream.write mà không thực sự viết tệp trên đĩa không?

Cảm ơn Anand

+1

Xin làm rõ - nơi nào bạn tạo ra một 'OutputStreamWriter' - Tôi không nhìn thấy nó trong mã của bạn. Tôi đoán rằng nó nằm trong 'getOutputStream' - ngoại trừ việc bạn đã loại bỏ phương thức này. Bạn cần đăng tất cả mã của mình nếu bạn muốn mọi người làm tốt công việc giúp bạn. Ngoài ra, 'getOutputStream' có thể được gọi là cái gì đó khác (có thể là' makeWriter'), bởi vì nó không nhận được một 'OutputStream'. –

+0

Trong phương thức getOutputStream. Lý do tôi chuyển nó sang phương pháp với hy vọng rằng mockito sẽ không chạy mthod và trả lại mô hình. nhưng tôi sai. – Anand

+0

Sau khi googling và đọc vài tài liệu phát hiện ra rằng PowerMock có thể làm điều này một cách dễ dàng. Với expectNew hoặc sử dụng suppressConstructor và Whitebox.setInsternalState. Thật dễ dàng để thử nghiệm những thứ như vậy với PowerMock. Cảm ơn tất cả các bình luận và câu trả lời của bạn ..kính trọng, Anand Barhate – Anand

Trả lời

9

Bạn có thể sử dụng ByteArrayOutputStream mà ghi dữ liệu trong bộ nhớ. Bạn có thể đọc nó với ByteArrayInputStream.

Một cách khác là viết OutputStream mong đợi không thành công ngay khi bạn cố viết một byte không chính xác. Điều này có thể hữu ích để xem chính xác vị trí/tại sao thử nghiệm không thành công.

+0

Ok .. vì vậy sử dụng ByteArrayOutputStream để viết và sau đó cuối cùng tôi sẽ phải sử dụng writeTo để ghi vào tập tin? Nhưng sớm hay muộn tôi sẽ đối mặt với cùng một vấn đề, phải không? XXStreamWriter sẽ phải viết tập tin và đó là bit tôi muốn tránh sử dụng Mockito. – Anand

+1

Tôi không hiểu. Tại sao bạn cần phải ghi vào một tập tin? –

0

Bạn nên giả lập getOutputStream: sẽ trả về đối tượng luồng đầu ra được mô phỏng. Yêu cầu new FileOutputStream thực sự tạo tệp trên đĩa.

Về mặt lý thuyết, bạn có thể giả lập hệ thống tệp nhưng nó phức tạp hơn nhiều.

Và BTW if(outputStream != null) là dự phòng: luồng không bao giờ có thể rỗng. Nếu nó không thể được tạo ra, phương thức nên ném ngoại lệ. Nó không phải là C, nó là Java. :)

+0

Thực ra đây là những gì tôi đã làm \t \t khi (testObj.getOutputStream (outputFileNameValidValue)). ThenReturn (outputStreamMock); nhưng khi tôi gọi \t \t testObj.write (outputFileNameValidValue, reveredFileInput); nó sẽ vẫn ghi chuỗi trắng vào tệp. Vì vậy, có vẻ như tôi sẽ phải giả lập hệ thống tập tin để tránh thực sự tạo ra một tập tin trên đĩa. – Anand

+0

nếu (outputStream! = Null) đồng ý về điều này. Tôi chỉ được sử dụng để lập trình phòng thủ :) – Anand

0

Bạn nên có mô hình getOutputStream(String) trả lại java.io.StringWriter và sau đó bạn có thể khẳng định rằng nội dung dự kiến ​​đã được viết.

public void testFileWrite() throws IOException { 
    StringWriter writer = new StringWriter(); 
    when(testObj.getOutputStream(outputFileNameValidValue)).thenReturn(writer); 

    testObj.write(outputFileNameValidValue, reveredFileInput); 

    assertEquals(reveredFileInput, writer.toString()); 

    verify(writer).close(); 
} 
1

Như đã đề xuất khác, bạn cần có khả năng đưa ra một OutputStream giả trong lớp của bạn đang được kiểm tra. Khi lớp của bạn được kiểm tra cần một OutputStream ghi vào một tệp đã cho, bạn sẽ cần phải đưa ra một OutputStreamFactory có thể mô phỏng được vào lớp của bạn đang được kiểm tra.

tôi có mã này cho bạn đó là hoàn toàn khép kín:

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mock; 
import org.mockito.runners.MockitoJUnitRunner; 

import java.io.IOException; 
import java.io.OutputStream; 

import static org.mockito.Mockito.verify; 
import static org.mockito.Mockito.when; 

@RunWith(MockitoJUnitRunner.class) 
public class Test9328173 { 

    private ClassUnderTest testObj; 

    @Mock 
    private OutputStreamFactory factory; 

    @Mock 
    private OutputStream stream; 

    @Before 
    public void setUp() throws Exception { 
     testObj = new ClassUnderTest(); 
     testObj.factory = factory; 
    } 

    @Test 
    public void testFileWrite() throws Exception { 
     when(factory.create("filename")).thenReturn(stream); 

     testObj.write("filename", new byte[]{1, 2, 3}); 

     verify(stream).write(new byte[]{1, 2, 3}); 
     verify(stream).close(); 
    } 

    private class ClassUnderTest { 

     private OutputStreamFactory factory; 

     public void write(String filename, byte[] content) throws IOException { 
      OutputStream stream = factory.create(filename); 
      try { 
       stream.write(content); 
      } finally { 
       stream.close(); 
      } 
     } 
    } 

    private interface OutputStreamFactory { 

     OutputStream create(String filename); 
    } 
} 
+0

Thật vậy. Một đối số setter/constructor/chú thích @Inject có thể dễ dàng hơn một chút so với một nhà máy, nhưng đây là cách để xác minh rằng luồng nhận được các chỉ dẫn đúng. – avandeursen

Các vấn đề liên quan