简体   繁体   English

如何在API控制器的单元测试中注册我的System.Web.Security.Membership以避免此问题?

[英]How should register my System.Web.Security.Membership to avoid this issue in the unit test of an API controller?

I created a unit test to a log in a user, using an api controller and the membership is checking the user that is in my Dto using this line of code. 我使用api控制器为用户的日志创建了一个单元测试,并且成员身份正在使用此代码行检查Dto中的用户。

  MembershipUser membershipUser = System.Web.Security.Membership.GetUser(Username);

On the web application this is working well, but on the test project and my unit test I am having this exception. 在Web应用程序上,它运行良好,但是在测试项目和单元测试中,我遇到了此异常。

Access to the path 'C:\\PROGRAM FILES (X86)\\MICROSOFT VISUAL STUDIO 12.0\\COMMON7\\IDE\\COMMONEXTENSIONS\\MICROSOFT\\TESTWINDOW\\App_Data' is denied. 拒绝访问路径“ C:\\ PROGRAM FILES(X86)\\ MICROSOFT VISUAL STUDIO 12.0 \\ COMMON7 \\ IDE \\ COMMONEXTENSIONS \\ MICROSOFT \\ TESTWINDOW \\ App_Data”。

How should register my System.Web.Security.Membership to avoid this issue in the unit test? 如何在单元测试中注册System.Web.Security.Membership以避免此问题?

My test method looks like this: 我的测试方法如下:

  [TestMethod]
  public void LoginSuccessfullyAnUser()
  {
      //Arrange
      var controller = new TokensController(unitOfWork, unitOfWorkMembership, configManager);
      var credentials = new LoginUserDTO
                             { 
                                 Username = "user1", 
                                 Password = "12345678" 
                              };

      controller.Request = new HttpRequestMessage 
      {
           RequestUri = new Uri("http://localhost/api/tokens")
      };

      controller.Configuration = new HttpConfiguration();
      controller.Configuration.Routes.MapHttpRoute(name: "DefaultApi", 
                                         routeTemplate: "api/{controller}/{id}",
                                         defaults: new { id = RouteParameter.Optional });

      controller.RequestContext.RouteData = new HttpRouteData(route: new HttpRoute(),
                                                             values: new HttpRouteValueDictionary 
                                                                            { 
                                                                              { "controller", "tokens" } 
                                                                            });

      //Act
      var response = controller.Post(credentials);

      //Assert
      Assert.IsNotNull(response);
}

You will have to wrap Membership around a class eg MembershipService. 您将必须将Membership封装在一个类上,例如MembershipService。 All the membership API you are invoking will be redirected through this class. 您正在调用的所有成员资格API都将通过此类重定向。 This basically give you the ability to mock the actual Membership class behavior in Unit Test. 这基本上使您能够模拟单元测试中的实际Membership类行为。

So let's see some code: 因此,让我们看一些代码:

Controller.cs Controller.cs

[HttpPost]
public JsonResult GetLoggedInUserName()
{
    MembershipUser mem = _membershipService.GetUserDetails(User.Identity.Name);

    Guid membershipId = new Guid(mem.ProviderUserKey.ToString());
    var organizationUser = _organizationUserService.GetUserDetailsByMembershipId(membershipId);
    var  name = organizationUser.FirstName + " " + organizationUser.LastName;

    return Json(name);
}

MembershipService.cs MembershipService.cs

public class MembershipService : IMembershipService
{
    public MembershipUser GetUserDetails(string emailAddress)
    {
        return Membership.GetUser(emailAddress);
    }
}

MyTests.cs MyTests.cs

    [TestMethod()]
    public void GetLoggedInUserName_InvokedWithValidSetup_ReturnUserName()
    {
        // Arrange

        // Setup membership to return mocked user
        var membershipService = new Mock<IMembershipService>();

        var user = new Mock<MembershipUser>();
        user.Setup(x => x.UserName).Returns("Adam");
        user.Setup(x => x.ProviderUserKey).Returns("1df03f8c-74fa-423a-8be8-61350b4da59f");
        user.SetupGet(x => x.Email).Returns("adamw@test.com");

        membershipService.Setup(m => m.GetUserDetails(It.IsAny<string>())).Returns(user.Object);

        // Setup organization user service - You can ignore it or replace
        // based on what you are using.
        var organizationUserService = new Mock<IOrganizationUserService>();
        var organizationUser = new OrganizationUser
        {
            FirstName = "Adam",
            LastName = "Woodcock",
            MembershipId = new Guid("1df03f8c-74fa-423a-8be8-61350b4da59f")
        };
        organizationUserService.Setup(s => s.GetUserDetailsByMembershipId(It.IsAny<Guid>())).Returns(organizationUser);

        var mock = new Mock<ControllerContext>();
        mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("Adam");
        var target = GetTargetController(membershipService, null, organizationUserService, null, null);
        target.ControllerContext = mock.Object;

        // Act
        var result = target.GetLoggedInUserName();

        // Assert
        Assert.AreEqual(organizationUser.FirstName + " " + organizationUser.LastName, result.Data);
    }

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM