我有一个方法很少的api。我需要先通过Windows Authentication
对用户进行身份验证,然后才能访问任何控制器方法。为此,我编写了一个私有方法来获取UserIdentity
并将其分配给私有bool
变量。
每种控制器方法都将首先检查布尔值以验证用户,如果失败,则会将401
返回前端。
在将单元测试用例写入控制器方法的同时,我不确定如何模拟UserIdentity
还是应该以允许测试UserIdentity
的方式更新控制器
控制器:
public class DefaultController : ApiController
{
private bool isUsrAuthenticated;
public DefaultController()
{
AuthenticateUser();
}
private void AuthenticateUser()
{
isUsrAuthenticated = User.Identity.IsAuthenticated;
}
[HttpGet]
public IHttpActionResult GetProducts()
{
if (isUsrAuthenticated) { // do something }
else { // throw 401 }
}
[HttpPost]
public IHttpActionResult Update()
{
if (isUsrAuthenticated) { // do something }
else { // throw 401 }
}
}
单元测试结果始终返回401。
答案 0 :(得分:0)
在运行时,调用控制器的构造函数后,将ApiController.User
属性设置得很好。这意味着您当前在构造器中调用它的流程就像
public DefaultController() {
AuthenticateUser();
}
存在缺陷,无法提供预期的行为。
让我们先修复代码,然后查看单元测试。
使用类似的属性
private bool IsUserAuthenticated {
get {
return User.Identity.IsAuthenticated;
}
}
并相应地重构代码
public class DefaultController : ApiController {
private bool IsUserAuthenticated {
get {
return User.Identity.IsAuthenticated;
}
}
[HttpGet]
public IHttpActionResult GetProducts() {
if (IsUserAuthenticated) { // do something }
else { // throw 401 }
}
[HttpPost]
public IHttpActionResult Update() {
if (IsUserAuthenticated) { // do something }
else { // throw 401 }
}
//...
}
现在,为了测试ApiController
,可以在安排单元测试时设置User
属性,以使测试按预期进行
例如
[TestMethod()]
public void DefaultController_Should_GetProducts() {
//Arrange
var username = "name_here";
var userId = 2;
var identity = new GenericIdentity(username, "");
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId.ToString()));
identity.AddClaim(new Claim(ClaimTypes.Name, username));
var principal = new GenericPrincipal(identity, roles: new string[] { });
var user = new ClaimsPrincipal(principal);
var controller = new DefaultController() {
User = user //<-- Set the User on the controller directly
};
//Act
var actionResult = controller.GetProducts();
//Assert
//...
}