2013-05-14 40 views
11

Tôi đang cố gắng thực hiện thói quen viết bài kiểm tra đơn vị, tôi đã viết một vài trước đây nhưng chúng thường khá cơ bản ... Tôi muốn bắt đầu thực hiện để TDD như tôi muốn cải thiện chất lượng của mã của tôi (thiết kế và cấu trúc) - giảm khớp nối, trong khi cùng một lúc hy vọng giảm số hồi quy mà trượt qua để xây dựng một thử nghiệm.Phương pháp thử nghiệm đơn vị với tệp IO

Tôi đã thực hiện một dự án tương đối đơn giản mà tôi bắt đầu thực hiện. Chương trình kết quả theo dõi một thư mục và sau đó hoạt động trên các tệp trong thư mục này.

Dưới đây là một ví dụ điển hình của một số mã được chiết xuất từ ​​dự án:

private string RestoreExtension(String file) 
    { 
     var unknownFile = Path.GetFileName(file); 
     var ignoreDir = Path.GetDirectoryName(file) + "\\Unknown"; 
     string newFile; 

     //We need this library for determining mime 
     if (CheckLibrary("urlmon.dll")) 
     { 
      AddLogLine("Attempting to restore file extension"); 
      var mime = GetMimeType(BufferFile(file, 256)); 
      var extension = FileExtensions.FindExtension(mime); 
      if (!String.IsNullOrEmpty(extension)) 
      { 
       AddLogLine("Found extension: " + extension); 
       newFile = file + "." + extension; 
       File.Move(file, newFile); 
       return newFile; 
      } 
     } 
     else 
     { 
      AddLogLine("Unable to load urlmon.dll"); 
     } 

     AddLogLine("Unable to restore file extension"); 

     if (!Directory.Exists(ignoreDir)) 
     { 
      Directory.CreateDirectory(ignoreDir); 
     } 
     var time = DateTime.Now; 
     const string format = "dd-MM-yyyy HH-mm-ss"; 

     newFile = ignoreDir + "\\" + unknownFile + "-" + time.ToString(format); 
     File.Move(file, newFile); 

     return String.Empty; 
    } 

Câu hỏi:

Làm thế nào tôi có thể thử nghiệm một phương pháp sử dụng IO? Tôi không thực sự muốn sử dụng một tập tin thực sự vì điều này sẽ chậm (và nhiều hơn nữa của một bài kiểm tra tích hợp?), Nhưng tôi không thể thực sự nhìn thấy một cách khác. Tôi có thể thêm một lớp trừu tượng IO có thể chuyển đổi, nhưng điều này nghe với tôi như nó có thể làm phức tạp mã không cần thiết ...

Là một dự án như thử nghiệm đơn vị có giá trị này? Ý tôi là, nó quá đơn giản. Một khi bạn thoát ra ngoài. Net và các cuộc gọi thư viện của bên thứ ba không còn nhiều nữa ... Vậy có phải là một trường hợp mà số lượng công việc để làm cho nó có thể kiểm chứng có nghĩa là nó không phải là một ứng cử viên tốt để kiểm tra?

Rất nhiều phương pháp trong dự án này là riêng tư, vì dự án này xảy ra là dịch vụ cửa sổ. Tôi đã đọc bạn chỉ nên thực sự thử nghiệm các phương pháp được bên ngoài có thể nhìn thấy (công khai hoặc tiếp xúc thông qua một giao diện), nó không chắc trong trường hợp này tuy nhiên tôi muốn phơi bày bất kỳ phương pháp của riêng tôi. Vì vậy, dự án này có giá trị thử nghiệm (như id có lẽ cần phải hoặc là thay đổi phương thức truy cập phương thức công khai hoặc thêm một số thuộc tính để NUnit có thể nhìn thấy chúng)?

Cheers

+0

tôi biết điều này là cũ, nhưng nó dễ dàng hơn để sử dụng Microsoft Fakes – zaitsman

Trả lời

10

Về làm thế nào để kiểm tra tập tin I/O: Một cách phổ biến để làm điều này được đóng gói File I/O trong một lớp wrapper. Ví dụ:

public class FileHandler : IFileHandler 
{ 
    public string GetFilename(string name) 
    { 
     return System.IO.GetFileName(name); 
    } 

    public string GetDirectoryName(string directory) 
    { 
     return System.IO.GetDirectoryName(directory); 
    } 
} 

public interface IFileHandler 
{ 
     string GetFilename(string name); 
     string GetDirectoryName(string directory); 
} 

Trong phương pháp thử nghiệm, bạn chỉ lập trình chống lại giao diện. Khi bạn chạy thử nghiệm đơn vị của mình, bạn sẽ sử dụng đối tượng giả để trả về các giá trị được xác định trước. Đối với điều này, bạn có thể sử dụng Moq.

Đây là một chút việc phải làm nhưng sau đó bạn không cần phải kiểm tra tệp I/O.

nhất Jan

0

Tôi khá mới với TDD quá, nhưng tôi nghĩ rằng tôi có thể nhận được một số gợi ý cho bạn:

  1. Về kiểm tra IO. Bạn có thể sử dụng các đối tượng giả giả. Tạo một mô hình cho phương thức bạn muốn kiểm tra và so sánh nó với giá trị thực được truyền. Trong khung Moq, có vẻ như:

    var mock = new Mock<IRepository<PersonalCabinetAccount>>(); 
    mock.Setup(m => m.RemoveByID(expectedID)) 
        .Callback((Int32 a) => Assert.AreEqual(expectedID, a)); 
    
    var account = new PersonalCabinetAccount {ID = myID}; 
    var repository = mock.Object; 
    repository.RemoveByID(account.myId); 
    
  2. Tuyệt đối, có. Nếu bạn muốn có thói quen, bạn cần kiểm tra mọi thứ, tôi cho là vậy. Theo cách đó, kiến ​​thức xuất hiện;)

  3. Bạn có thể sử dụng thuộc tính InternalsVisibleTo để tránh các vấn đề về mức hiển thị.

    phương pháp thử nghiệm mà là từ bên ngoài có thể nhìn thấy

Tôi nghĩ cái này về lập trình doanh nghiệp. chỉ là một thời gian rảnh với mã đáng tin cậy của riêng bạn.

Hy vọng quan điểm của tôi có thể giúp bạn.

5

Tôi có thể thử nghiệm một phương thức bằng IO bằng cách nào?

Bằng cách giới thiệu trừu tượng qua thư viện IO của .NET và sau đó sử dụng thực thi thực tế (BCL) trong ứng dụng và giả (thử) trong thử nghiệm đơn vị. Sự trừu tượng như vậy là khá đơn giản để viết trên của riêng bạn, nhưng những dự án đó đã tồn tại (ví dụ: System.IO.Abstraction) để tái phát minh bánh xe là vô nghĩa, đặc biệt trong vấn đề tầm thường này.

Tôi không thực sự muốn được sử dụng một tập tin thực như thế này sẽ chậm

này là đúng, trong thử nghiệm bạn muốn sử dụng fake (mock) objects.

Đây có phải là dự án như thử nghiệm đơn vị đáng giá này không?

Mọi dự án đều đáng thử nghiệm và bạn sẽ kiểm tra theo cách này hay cách khác (trong trường hợp cực đoan nhất, bằng cách thực hiện thủ công ứng dụng và thực hiện thử nghiệm nhấp và chờ tốt). Lưu ý rằng hầu như luôn luôn mất quá nhiều thời gian để kiểm tra thủ công 10 trường hợp cạnh của phương thức phân tích cú pháp phức tạp mà mỗi lần yêu cầu bạn tải tệp lớn và chờ kết quả. Đây là nơi thử nghiệm tự động trong môi trường bị cô lập giúp ích rất nhiều. Nó giống với hệ thống tập tin mã, dịch vụ web của bạn, tất cả đều giới thiệu chi phí lớn trước khi bạn có thể thực hiện logic kinh doanh thực tế. Phải cô lập.

Rất nhiều các phương pháp trong dự án này là tư nhân (...) Tôi đã đọc bạn chỉ nên thực sự phương pháp thử nghiệm mà là từ bên ngoài có thể nhìn thấy

đúng một lần nữa, bạn nên kiểm tra hợp đồng công cộng . Tuy nhiên, nếu công cụ riêng tư đủ lớn để kiểm tra nó, hầu hết thời gian đó là một chỉ báo tốt, nó cũng đủ lớn để đưa nó vào lớp riêng của nó. Lưu ý rằng việc thay đổi thành viên chỉ truy cập các công cụ sửa đổi cho việc sử dụng thử nghiệm đơn vị không phải là ý tưởng tốt nhất. Hầu như lúc nào cũng tốt hơn để giải nén lớp/phương thức tái cấu trúc.

0

Bạn có thể làm điều đó bằng cách sử dụng Microsoft Fakes. Đầu tiên generate a fake assembly cho System.dll - hoặc bất kỳ gói khác và sau đó thử lại trông đợi như trong:

using Microsoft.QualityTools.Testing.Fakes; 
... 
using (ShimsContext.Create()) 
{ 
    System.IO.Fakes.ShimDirectory.ExistsString = (p) => true; 
    System.IO.Fakes.ShimFile.MoveStringString = (p,n) => {}; 
    // .. and other methods you'd like to test 

    var result = RestoreExtension("C:\myfile.ext"); 
    // then you can assert with this result 
} 
Các vấn đề liên quan