2010-03-29 18 views
5

Tôi đang viết một số bài kiểm tra đơn vị cho một phương pháp mở rộng mà tôi đã viết trên IPrincipal. Để hỗ trợ, tôi đã tạo ra một vài lớp helper (một số mã để các thành viên không-thực hiện các giao diện đã được bỏ qua cho ngắn gọn):Làm thế nào để bạn tạo một bài kiểm tra đơn vị cho một giao diện có chứa một thành viên chỉ đọc?

public class IPrincipalStub : IPrincipal 
{ 
    private IIdentity identityStub = new IIdentityStub(); 

    public IIdentity Identity 
    { 
     get { return identityStub; } 
     set { identityStub = value; } 
    } 
} 

public class IIdentityStub : IIdentity 
{ 
    public string Name { get; set; } // BZZZT!!! 
} 

Tuy nhiên, Name tài sản trong giao diện IIdentity là read-only (giao diện IIDentity chỉ định trình thu thập chứ không phải trình thiết lập cho thuộc tính Tên).

Làm cách nào để đặt thuộc tính Tên trong đối tượng gốc của tôi cho mục đích thử nghiệm nếu giao diện đã xác định nó là thuộc tính chỉ đọc?

+0

Constructor? tức là 'IIdentityStub' sẽ có một hàm tạo tham số nhận tên là tham số. – shahkalpesh

+0

"BZZZT" của bạn có phải là lỗi biên dịch không? Tôi đã có thể biên dịch mẫu của bạn tốt (w/bán dấu hai chấm trên tài sản Identity, đó là). – micahtan

+0

@micahtan: Có, nhưng khi bạn cố gắng viết một bài kiểm tra với nó, và đặt giá trị 'Tên' trong bài kiểm tra, trình biên dịch sẽ phàn nàn rằng' Tên' là chỉ đọc, vì thuộc tính 'Name' trong' IIDentity' không có setter được xác định. –

Trả lời

3

Bạn đang sử dụng tính năng tự động thuộc tính của C# nhưng thay vào đó bạn nên đi theo tuyến đường thủ công và tạo trường sao lưu cho thuộc tính. Một khi bạn có một trường sao lưu, bạn có thể đặt giá trị của nó trong hàm tạo (hoặc làm cho nó là một trường công khai và thiết lập nó sau khi bạn có đối tượng, nhưng điều này là một chút xấu xí hơn).

public class IIdentityStub : IIdentity{ 
    private string _name; 

    public IIdentityStub(string name){ 
     _name = name; 
    } 

    public string Name { get { return _name; } } 
} 
+0

Và nếu giá trị không thể đặt được thông qua hàm tạo, bạn có vấn đề với thiết kế của mình. –

+0

Tuyệt vời, cảm ơn. –

+0

@ Robert Harvey: Không sao cả. –

1

tôi khuyên bạn nên sử dụng một thư viện Mock như NMock

+1

Đúng, nhưng tôi nghĩ tôi nên học cách viết bài sơ khai của riêng mình trước. –

2

Tôi đồng ý với juharr - sử dụng một khuôn khổ mocking/ly. Tôi muốn giới thiệu Moq.

Sau đây sẽ in "Robert":

using System; 
using System.Security.Principal; 
using Moq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main() 
     { 
      var mockIdentity = new Mock<IIdentity>(); 
      var mockPrincipal = new Mock<IPrincipal>(); 

      mockIdentity.SetupGet(x => x.Name).Returns("Robert"); 
      mockPrincipal.SetupGet(x => x.Identity).Returns(mockIdentity.Object); 

      IPrincipal myStub = mockPrincipal.Object; 

      Console.WriteLine(myStub.Identity.Name); 
     } 
    } 
} 

EDIT: Nhưng nếu bạn muốn làm điều đó bằng tay ...

using System; 
using System.Security.Principal; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main() 
     { 
      IIdentity identity = 
       new IdentityStub 
        { 
         Name = "Robert", 
         AuthenticationType = "Kerberos", 
         IsAuthenticated = true 
        }; 

      IPrincipal principal = new PrincipalStub(identity); 

      Console.WriteLine(principal.Identity.Name); // Robert 
      Console.WriteLine(principal.IsInRole(PrincipalStub.ValidRole)); // True 
      Console.WriteLine(principal.IsInRole("OtherRole")); // False 
     } 
    } 

    public class PrincipalStub : IPrincipal 
    { 
     public const string ValidRole = "TestRole"; 

     public PrincipalStub(IIdentity identity) 
     { 
      Identity = identity; 
     } 

     public IIdentity Identity { get; private set; } 

     public bool IsInRole(string role) 
     { 
      return role == ValidRole; 
     } 
    } 

    public class IdentityStub : IIdentity 
    { 
     public string Name { get; set; } 
     public string AuthenticationType { get; set; } 
     public bool IsAuthenticated { get; set; } 
    } 
} 

(Trên đây là không một kiểm tra đơn vị, chỉ là một ví dụ về các cuống tay được cán bằng cách sử dụng một chút tiêm phụ thuộc.)

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