我有一个自定义的
CodeAccessSecurityAttribute
即连接外部源以进行验证。
[Serializable]
[AttributeUsage(AttributeTargets.Method)]
public class IsAuthorizedAttribute : CodeAccessSecurityAttribute
{
private static readonly PrincipalPermission Allowed = new PrincipalPermission(PermissionState.None);
private static readonly PrincipalPermission NotAllowed = new PrincipalPermission(PermissionState.Unrestricted);
public string EntityObject { get; set; }
public string Field { get; set; }
public char Expected { get; set; }
public IsAuthorizedAttribute(SecurityAction action)
: base(action)
{
//setup
}
public override IPermission CreatePermission()
{
return IsAuthorised(EntityObject, Field, Expected, ServicesConfiguration) ? Allowed : NotAllowed;
}
private static bool IsAuthorised(string entityObject, string field, char expected, ServicesConfiguration servicesConfiguration)
{
bool? response = null;
//check external stuff
return response ?? false;
}
}
我用这个属性修饰了我的方法:
[IsAuthorized(SecurityAction.Demand, EntityObject = Fields.UserManagement, Field = Fields.AllowDisplay, Expected = '1')]
public List<Group> GetUserGroups()
{
var response = new List<Group>();
//Get the groups from the database
var groups = groupManager.FindAll();
//Map them to the output group type
response = groups.Select(x => new Group()
{
ID = x.ID,
Name = x.Name,
Alias = x.Alias,
Description = x.Description
}).ToList();
return response;
}
我现在想对这个方法进行单元测试,但是属性被激发了。我试过一些东西来嘲弄这个属性,但是没有成功。
我用的是最小起订量和
Smocks
.
这是我的单元测试,没有属性的模拟实例:
[TestMethod]
public void GetUserGroups_UserGroupsFound_UserGroupsReturned()
{
Smock.Run(context =>
{
//Arrange
Setup();
m_Container
.RegisterMock<IGroupManager>()
.Setup(x => x.FindAllFromCache())
.Returns(new List<Concept.Security.MasterData.Domain.Group>()
{
new Concept.Security.MasterData.Domain.Group()
{
Name = "MyUserGroup",
Alias = "My User Group",
Description = "My user group description",
System = false,
Authorizations = "000001111100000000"
},
new Concept.Security.MasterData.Domain.Group()
{
Name = "MySecondUserGroup",
Alias = "My Second User Group",
Description = "My second user group description",
System = false,
Authorizations = "000000000000000000"
}
});
var identityService = new UserManagementService(m_Container, m_UserAuthorizationManager.Object, m_IdentityService.Object);
//** begin add mocked attribute **//
//** end add mocked attribute **//
//Act
var response = identityService.GetUserGroups();
//Assert
Assert.AreEqual(2, response.Count);
Assert.AreEqual(1, response.Where(x => x.Alias == "MyUserGroup").Count());
Assert.AreEqual(1, response.Where(x => x.Alias == "MySecondUserGroup").Count());
Assert.AreEqual(2, response.Where(x => x.Authorizations == null).Count());
});
}
运行此操作会导致异常,因为该属性尝试连接外部服务,但它们没有(也无法)设置为接收请求。
//** begin add mocked attribute **//
var identityService = new UserManagementService(m_Container, m_UserAuthorizationManager.Object, m_IdentityService.Object);
var IsAuthorizedAttribute = new Mock<IsAuthorizedAttribute>(MockBehavior.Strict, new object[] { SecurityAction.Demand });
IsAuthorizedAttribute.Setup(x => x.CreatePermission()).Returns(new PrincipalPermission(PermissionState.None));
TypeDescriptor.AddAttributes(identityService, IsAuthorizedAttribute.Object);
//** end add mocked attribute **//
但是这个调用的是我设置外部源的属性的构造函数。当我将此构造函数放入try/catch并静默地处理异常时,在
IsAuthorizedAttribute.Object对象
还有哪些不触发属性的选项?