我有点试图弄清楚如何测试以下内容: 这是GetProjects方法。
[Authorize]
[HttpGet]
[Route("api/UserProject/GetUserProjects")]
public HttpResponseMessage GetProjects()
{
string userId = User.Identity.GetUserId();
if (!ModelState.IsValid)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
try
{
List<ProjectDto> userProjectsDtos = projectBll.GetProjects(userId);
return Request.CreateResponse(HttpStatusCode.OK, userProjectsDtos);
}
catch (Exception)
{
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
}
在这里,我尝试为该方法运行NUnit测试。
[TestClass]
public class TestUserProjects
{
[TestMethod]
public void GetUserProjectsTest()
{
// Arragnge
var controller = new UserProjectController();
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
foreach (var testUserId in GetTestUserIds())
{
// Act
var response = controller.GetProjects();
// Assert
List<ProjectDto> projects;
Assert.IsTrue(response.TryGetContentValue<List<ProjectDto>>(out projects));
//Assert.AreEqual(5, projects.Count); // Check projects count
Assert.AreEqual(HttpStatusCode.OK,response.StatusCode);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode,"GetUserProjects : id is {0} and count is {1}",testUserId,projects.Count);
System.Diagnostics.Debug.WriteLine("GetUserProjects : for id {0} ProjectCount = {1}", testUserId, projects.Count);
}
}
}
我正在尝试传递 userId ,但不知道在哪里写。
答案 0 :(得分:1)
它不是“可模仿的”,你应该创建一个不同的函数,它将接收用户名作为参数。
您的WebAPI将调用该函数,您的测试将测试逻辑。
答案 1 :(得分:1)
静态访问会创建在测试期间无法轻易忽略的硬依赖项。
解决方案是将该依赖性从测试中的方法中拉出来。我会这样做,在测试时可以模拟IUserProvider
依赖项,并提供适合测试的任何用户ID。
public interface IUserProvider
{
public string GetUserId();
}
public class UserProvider : IUserProvider
{
public string GetUserId()
{
return User.Identity.GetUserId();
}
}
public class UserProjectController
{
private IUserProvider UserProvider { get; set;}
public UserProjectController(IUserProvider userProvider)
{
UserProvider = userProvider;
}
[Authorize]
[HttpGet]
[Route("api/UserProject/GetUserProjects")]
public HttpResponseMessage GetProjects()
{
string userId = UserProvider.GetUserId();
if (!ModelState.IsValid)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
try
{
List<ProjectDto> userProjectsDtos = projectBll.GetProjects(userId);
return Request.CreateResponse(HttpStatusCode.OK, userProjectsDtos);
}
catch (Exception)
{
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
}
}
测试时模拟IUserProvider的语法将随着不同的测试框架而改变。使用Moq看起来像这样
[TestClass]
public class TestUserProjects
{
[TestMethod]
public void GetUserProjectsTest()
{
// Arrange
var userProviderMock = new Mock<IUserProvider>();
userProviderMock.Setup(userProvider => userProvider.GetUserId())
.Returns("4e934c03-b02f-47bf-8bdf-e1c98a737cc6");
var controller = new UserProjectController(userProviderMock.Object);
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
foreach (var testUserId in GetTestUserIds())
{
// Act
var response = controller.GetProjects();
// Assert
List<ProjectDto> projects;
Assert.IsTrue(response.TryGetContentValue<List<ProjectDto>>(out projects));
//Assert.AreEqual(5, projects.Count); // Check projects count
Assert.AreEqual(HttpStatusCode.OK,response.StatusCode);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode,"GetUserProjects : id is {0} and count is {1}",testUserId,projects.Count);
System.Diagnostics.Debug.WriteLine("GetUserProjects : for id {0} ProjectCount = {1}", testUserId, projects.Count);
}
}
}
编辑部分new中的第一行创建了IUserProvider
模拟并设置GetUserId()
以返回测试用户ID。
答案 2 :(得分:1)
如果要求对请求进行身份验证,则应使用经过身份验证的用户的原则填充User
属性。在单元测试期间,框架不会填充此内容。
对于ApiController
,您可以在安排单元测试期间设置User
属性。然而,GetUserId()
扩展方法正在寻找ClaimsIdentity
,因此您应该提供一个
[TestClass]
public class TestUserProjects {
[TestMethod]
public void GetUserProjectsTest() {
// Arrange
var controller = new UserProjectController();
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
foreach (var testUserId in GetTestUserIds()) {
//Arrange specific user
var identity = new GenericIdentity(testUserId, "");
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, testUserId.ToString()));
identity.AddClaim(new Claim(ClaimTypes.Name, testUserId.ToString()));
var principal = new GenericPrincipal(identity, roles: new string[] { });
var user = new ClaimsPrincipal(principal);
controller.User = user;
// Act
var response = controller.GetProjects();
// Assert
List<ProjectDto> projects;
Assert.IsTrue(response.TryGetContentValue<List<ProjectDto>>(out projects));
//Assert.AreEqual(5, projects.Count); // Check projects count
Assert.AreEqual(HttpStatusCode.OK,response.StatusCode);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode,"GetUserProjects : id is {0} and count is {1}",testUserId,projects.Count);
System.Diagnostics.Debug.WriteLine("GetUserProjects : for id {0} ProjectCount = {1}", testUserId, projects.Count);
}
}
}