Я пишу некоторые модульные тесты на дополнительный метод, на котором я записал 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
интерфейс указывает метод считывания, но не метод set для свойства Name).
Как я могу установить свойство Name в своем тупиковом объекте для тестирования, если интерфейс определил его как свойство только для чтения?
Вы используете функцию автоматического создания свойств в C #, но вместо этого вы должны пойти вручную и создать поле поддержки для свойства. Если у вас есть резервное поле, вы можете установить его значение в конструкторе (или сделать его публичным полем и установить его после того, как у вас есть объект, но это немного уродливее).
public class IIdentityStub : IIdentity{
private string _name;
public IIdentityStub(string name){
_name = name;
}
public string Name { get { return _name; } }
}
Я рекомендую использовать библиотеку Mock, например NMock
Я согласен с juharr - используйте фреймворк имитации / изоляции. Я бы порекомендовал Moq .
Следующее напечатает «Роберт»:
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; }
}
}
(Вышеупомянутый не модульный тест, просто пример скрученных вручную заглушек с использованием небольшой инъекции зависимостей .)