9

Tôi có một thư viện lớp tôi muốn thử nghiệm đơn vị bằng cách sử dụng khung kiểm tra đơn vị Microsofts. Một số lớp tôi muốn kiểm tra được định cấu hình bằng cài đặt ứng dụng. Các cài đặt này được xác định bên trong tệp Settings.settings có phạm vi ứng dụng và các giá trị mặc định phù hợp. Khi thư viện được ứng dụng sử dụng, các cài đặt này có thể bị ghi đè trong tệp App.Config. Nếu không sử dụng các giá trị mặc định. Đó chính xác là cách tôi muốn.Sửa đổi cài đặt ứng dụng trong các bài kiểm tra đơn vị

Trong một số trường hợp thử nghiệm, tôi muốn kiểm tra các kết hợp đặc biệt của giá trị cài đặt nhưng tôi không biết cách thay đổi giá trị mà lớp đang xem thử nghiệm từ mã kiểm tra đơn vị. Các cài đặt này sẽ luôn có giá trị mặc định của chúng được tải từ các thuộc tính của lớp được tạo mã.

Trong lớp thư viện của tôi, tôi truy cập vào các thiết lập như thế này:

var mySetting1 = Settings.Default.MySetting1; 
var mySetting2 = Settings.Default.MySetting2; 

Làm thế nào để sửa đổi các thiết lập trong một thử nghiệm đơn vị trước khi thiết lập được truy cập bởi các lớp dưới kiểm tra? Làm cho lớp cài đặt bên trong có thể truy cập bằng kiểm thử đơn vị không giải quyết vấn đề vì các thiết lập có phạm vi ứng dụng và là các thuộc tính chỉ đọc trên lớp cài đặt.

Trả lời

14

Sau spelunking vào ApplicationSettingsBase và đi kèm các lớp học tôi đã đi lên với giải pháp này cho vấn đề của tôi. Không đẹp đặc biệt, nhưng chắc chắn nó đã hoàn thành công việc.

Lớp cài đặt được tạo mã nằm bên trong dự án thư viện lớp và phải truy cập được vào dự án thử nghiệm đơn vị. Thêm thuộc tính [assembly: InternalsVisibleTo("UnitTestAssemblyName")] vào AssemblyInfo.cs trong dự án thư viện lớp học.

Cài đặt được tải chậm từ các thuộc tính trên lớp cài đặt khi truy cập giá trị. Bước đầu tiên là làm một "giả" đọc của một thiết lập để buộc tải lười biếng này. Khi thử nghiệm đơn vị bạn muốn tránh các giá trị cài đặt thay đổi trong một thử nghiệm để ảnh hưởng đến một giá trị khác do đó cần phải "đặt lại" cài đặt trước khi tải chúng xuống. Điều đó có thể được thực hiện bằng cách sử dụng phương thức Reload(). Mã này được đặt trong phương pháp khởi tạo thử nghiệm:

Settings.Default.Reload(); 
var dummy = Settings.Default.MySetting1; 

Giá trị cơ bản hiện có và có thể được đặt trong mỗi phương pháp thử nghiệm. Hãy nhớ sử dụng đúng loại như getters mã được tạo sẽ làm một dàn diễn viên:

Settings.Default.PropertyValues["MyStringSetting1"].PropertyValue = "Foobar"; 
Settings.Default.PropertyValues["MyDoubleSetting2"].PropertyValue = 3.1416D; 
+0

+1 cho giải pháp truy cập Reload + Property accessor. –

+0

Cảm ơn vì điều này, sẽ không bao giờ tự tìm ra nó. –

5

Tôi muốn tạo lớp bao bọc xung quanh lớp Settings rồi vượt qua trình bao bọc đó xung quanh. Sau đó, bạn có thể bỏ qua lớp cài đặt của mình một cách dễ dàng.

Điều duy nhất tôi có thể đưa ra là tùy chọn giả lập nhẹ hơn và dễ dàng hơn để tạo tệp cài đặt của bạn triển khai giao diện phản ánh tất cả cài đặt của bạn. Nó không thực sự khác nhiều so với người gọi, nhưng bạn sẽ có ít đường ống dẫn nước hơn để thực hiện khi thêm cài đặt mới.

Không tuyệt vời, và thật khó để làm điều đó cho mã được tạo tự động, nhưng có vẻ như đó là những gì chúng tôi đang mắc phải với điều kiện tôi thực sự muốn loại bỏ sự phụ thuộc vào tập tin cài đặt.

Ví dụ: cho một tập tin cài đặt có chứa một thiết lập chuỗi ứng dụng và thiết lập một int User:

internal sealed partial class Settings : IMySettings { 

    /* 
    * here be auto-generate code (and dragons!) 
    */ 
} 

internal interface IMySettings 
{ 
    string ApplicationSetting 
    { 
     get; 
    } 

    string UserSetting 
    { 
     get; 
     set; 
    } 
} 
+0

Tôi thà tránh thiết lập tiêm kể từ khi tôi có nhiều thư viện và số lượng phụ thuộc để tiêm mọc rất nhiều khi tôi di chuyển lên các bậc phụ thuộc .Ngoài ra, gói các lớp học được mã được tạo ra bởi Visual Studio là tẻ nhạt. Tôi đã hy vọng cho một giải pháp mà không phải là DI tinh khiết, nhưng sẽ làm việc tốt với các thiết lập ứng dụng trong .NET. –

+0

Thật không may tôi không nghĩ rằng có một, tốt nhất bạn có thể làm là thiết lập thiết lập người dùng, nhưng cài đặt ứng dụng sẽ không thay đổi bên ngoài tập tin. Điều duy nhất tôi có thể đưa ra vào lúc này là sử dụng một giao diện, nhẹ hơn một chút nhưng vẫn, như bạn nói, DI thuần túy. –

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