我正在为IPrincipal
上编写的扩展方法编写一些单元测试。为了提供帮助,我创建了几个辅助类(为简洁起见,省略了一些未实现的接口成员的代码):
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!!!
}
但是,Name
接口中的IIdentity
属性是只读的(IIDentity
接口指定getter但不指定Name属性的setter。)
如果接口已将其定义为只读属性,如何在存根对象中设置Name属性以进行测试?
答案 0 :(得分:3)
您正在使用C#的自动属性功能,但您应该使用手动路由并为该属性创建支持字段。一旦你有了一个支持字段,你可以在构造函数中设置它的值(或者将它设置为一个公共字段并在你拥有该对象后设置它,但这有点丑陋)。
public class IIdentityStub : IIdentity{
private string _name;
public IIdentityStub(string name){
_name = name;
}
public string Name { get { return _name; } }
}
答案 1 :(得分:2)
我同意juharr - 使用模拟/隔离框架。我建议Moq。
以下将打印“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);
}
}
}
编辑:但是,如果你想手工完成......
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; }
}
}
(以上是不单元测试,只是使用一点依赖注入的手动存根的示例。)
答案 2 :(得分:1)
我建议使用像NMock
这样的模拟库