2009-07-08 3 views
1

У меня есть следующий код для добавления/извлечения из Zip. Я пытаюсь реорганизовать это, чтобы сделать его готовым к тестированию. Может ли кто-нибудь указать указатели на то, как я могу это сделать? Помимо: Я использую Moq как мой макете рамки и MSTest как мой модульного тестирования инструментаМодульное тестирование Добавление к почтовому индексу/извлечение из почтового индекса

private const long BufferSize = 4096; 

public static void ExtractZip(string zipFilename, string folder) { 
    using (var zip = System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate)) { 
    foreach (var part in zip.GetParts()) { 
     using (var reader = new StreamReader(part.GetStream(FileMode.Open, FileAccess.Read))) { 
     using (var writer = new FileStream(folder + "\\" + Path.GetFileName(part.Uri.OriginalString), 
              FileMode.Create, FileAccess.Write)) { 
      var buffer = System.Text.Encoding.UTF8.GetBytes(reader.ReadToEnd()); 
      writer.Write(buffer, 0, buffer.Length); 
     } 
     } 
    } 
    } 
} 

public static void AddFileToZip(string zipFilename, string fileToAdd) { 
    using (var zip = System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate)) { 
    var destFilename = ".\\" + Path.GetFileName(fileToAdd); 
    var uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative)); 
    if (zip.PartExists(uri)) { 
     zip.DeletePart(uri); 
    } 
    var part = zip.CreatePart(uri, "", CompressionOption.Normal); 
    using (var fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read)) { 
     using (var dest = part.GetStream()) { 
     CopyStream(fileStream, dest); 
     } 
    } 
    } 
} 

Спасибо заранее.

+0

Это все выглядит довольно круто, но вы думали об использовании SharpZipLib делать то, что вы делаете? – Calanus

+0

@Calanus: Да, рассмотрит это в будущем ... Выполнение некоторых прототипов ... Схватил этот код из моего инструментария @ random. Спасибо за предложение, хотя :) –

ответ

2

Я хотел бы сделать эти два статических метода (ExtractZip и AddFileToZip) методы экземпляра, и поместить его в интерфейс:

public interface IZipper 
{ 
    void ExtractZip(string zipFilename, string folder); 
    void AddFileToZip(string zipFilename, string fileToAdd); 
} 

public class Zipper : IZipper 
{ 
    public void ExtractZip(string zipFilename, string folder) 
    { 
    //... 
    } 

    void AddFileToZip(string zipFilename, string fileToAdd) 
    { 
    //... 
    } 
} 


// client code 
class Foo 
{ 
    private IZipper myZipper; 
    // gets an instance of the zipper (injection), but implements only 
    // against the interface. Allows mocks on the IZipper interface. 
    public Foo(IZipper zipper) 
    { 
    myZipper = zipper; 
    } 

} 

код клиента теперь легко проверить.

Как насчет класса Zipper?

  • Рассмотрите, стоит ли в любом случае проверить.
  • В нашем проекте мы различаем отдельные тесты (изолированные) и интеграционные тесты, где можно использовать базу данных или файловую систему. Вы можете объявить его как «тест интеграции файловой системы». Конечно, разрешено использовать только тестовую целевую папку. Это не должно создавать никаких проблем.
  • Рассмотрите возможность перемещения операций с файлами и работайте только с потоками. Затем вы можете легко протестировать zipping на потоках памяти. Файловые операции все равно должны быть где-то и не тестироваться.
+0

@Stefan, спасибо за напоминание о клиентах (от zip-кода). Да, я буду издеваться над всей молнией для клиентов. еще раз для того, чтобы поделиться своими мыслями и помочь. –

0

Просветите создание FileStream s за IStreamProvider и передайте его AddFileToZip и ExtractZip. Вам придется абстрагироваться от действий файловой системы, если только вы не захотите делать диск ввода-вывода во время модульных тестов.

+0

@ Антон: Спасибо за ответ. Да, я понимаю, что это будет хорошим началом. Но как насчет открытия файла Zip (требуется, чтобы у меня был физический архив :()? –

0

Я вставляю окончательный код здесь, поскольку он может помочь кому-то, а также разрешить мне получать обратную связь. Спасибо Стефану за то, что он указал мне в правильном направлении.

/// <summary> 
/// The commented methods are marked for future 
/// </summary> 
public interface IZipper 
{ 
    //void Create(); 
    void ExtractAll(); 
    void ExtractAll(string folder); 
    //void Extract(string fileName); 
    void AddFile(string fileName); 
    //void DeleteFile(string fileName); 
} 
public interface IZipStreamProvider 
{ 
    Stream GetStream(string fileName); 
} 

public class ZipStreamProvider : IZipStreamProvider 
{ 
    public Stream GetStream(string fileName) 
    { 
     //Create a read/writable file 
     return new FileStream(fileName, FileMode.Create); 
    } 
} 

public class Zipper : IZipper 
{ 
    private const long BufferSize = 4096; 
    public string ZipFileName { get; set;} 

    //seam.. to use property injection 
    private IZipStreamProvider ZipStreamProvider { get; set;} 

    public Zipper(string zipFilename) 
    { 
     ZipFileName = zipFilename; 
     //By default, write to file 
     ZipStreamProvider = new ZipStreamProvider(); 
    } 

    public void ExtractAll() 
    { 
     ExtractAll(Environment.CurrentDirectory); 
    } 

    public void ExtractAll(string folder) 
    { 
     using (var zip = System.IO.Packaging.Package.Open(ZipStreamProvider.GetStream(ZipFileName))) 
     { 
      foreach (var part in zip.GetParts()) 
      { 
       using (var reader = new StreamReader(part.GetStream(FileMode.Open, FileAccess.Read))) 
       { 
        using (var writer = ZipStreamProvider.GetStream(folder + "\\" + Path.GetFileName(part.Uri.OriginalString))) 
        { 
         var buffer = System.Text.Encoding.UTF8.GetBytes(reader.ReadToEnd()); 
         writer.Write(buffer, 0, buffer.Length); 
        } 
       } 
      } 
     } 
    } 

    public void AddFile(string fileToAdd) 
    { 
     using (var zip = System.IO.Packaging.Package.Open(ZipFileName, FileMode.OpenOrCreate)) 
     { 
      var destFilename = ".\\" + Path.GetFileName(fileToAdd); 
      var uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative)); 
      if (zip.PartExists(uri)) 
      { 
       zip.DeletePart(uri); 
      } 
      var part = zip.CreatePart(uri, "", CompressionOption.Normal); 
      using (var fileStream = ZipStreamProvider.GetStream(fileToAdd)) 
      { 
       using (var dest = part.GetStream()) 
       { 
        CopyStream(fileStream, dest); 
       } 
      } 
     } 
    } 

    private long CopyStream(Stream inputStream, Stream outputStream) 
    { 
     var bufferSize = inputStream.Length < BufferSize ? inputStream.Length : BufferSize; 
     var buffer = new byte[bufferSize]; 
     int bytesRead; 
     var bytesWritten = 0L; 
     while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) != 0) 
     { 
      outputStream.Write(buffer, 0, bytesRead); 
      bytesWritten += bufferSize; 
     } 

     return bytesWritten; 
    } 
} 

+0

Я использую этот код для zip-файла XLS, но в то время как я его запишу, создавая XML-файл внутри ZIP-папки. Как я могу удалить этот XML-файл из ZIP-файла, поскольку я не хочу , пожалуйста, обратитесь к этой ссылке: http: //stackoverflow.com/questions/27035144/unexpected-xml-file-in-zip-file-created-when-compressing-an-xls-file-how-do-ip – HomeWork

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