如何最小起订量 Sitecore 用户对象?

问题描述 投票:0回答:1

我需要对以下原始方法进行起订量测试

public virtual User GetBOUser(string domainName, string userName, string password, Login model)
{
    try
    {
        if (Sitecore.Security.Accounts.User.Exists(domainName + @"\" + userName))
        {
            User user = Sitecore.Security.Accounts.User.FromName(domainName + @"\" + userName, true);
            return user;
        }
    }
    catch (Exception ex)
    {
        Log.Error("GetBOUser Error - " + ex.ToString(), this);
    }

    return null;
}

我创建的示例单元测试方法如下

[TestMethod]
public void LoginApiTest()
{            
    User use = null;            

    var mockapi = new Mock<ApiController>();
    mockapi.Setup(x => x.GetBOUser("", "", "", new Login())).Returns(use);

    var dataObject = mockapi.Object;

    Assert.AreEqual<User>(use, dataObject.GetBOUser("", "", "", new Login()));
}

这里我只能检查测试方法的返回类型中是否为 null,但是如何返回实际的

user
对象?

c# unit-testing sitecore moq sitecore8
1个回答
3
投票

在回答您的问题之前,我需要指出您的示例测试实际上并没有测试任何东西。 您正在模拟被测试的系统,告诉它返回 null,然后断言它返回 null。 这不会执行您的生产代码。

您应该创建 ApiController 的一个普通实例。 然而,这凸显了另一个问题,即您的方法依赖于 Sitecore 的静态安全 API。 如果您希望您的代码可测试,您将需要为该 API 创建一个接口和包装类,并让您的控制器在其构造函数中接受接口的实例,以便您可以为您的测试提供一个模拟实例,但提供一个真实的实例正在生产中。

您的包装类应该只调用静态 API 并且不应该包含任何逻辑。 这样你就不需要真正测试它了。 当您设置界面的模拟实例时,您可以创建一个模拟 IPrincipal 并将其传递给 User.FromPrincipal 以防止它实际尝试在数据库中查找用户。 如果您将接口命名为 IUserService,您的测试最终将看起来像这样:

[TestMethod]
public void GetBOUser_WithExistingUser_ReturnsUser()
{
    // Arrange
    var name = "Joe";
    var domain = "extranet";
    var fullName = domain + @"\" + name;

    var principal = new Mock<IPrincipal>();
    principal.Setup(p => p.Identity.Name).Returns(fullName);
    var joeUser = User.FromPrincipal(principal.Object);

    var userService = new Mock<IUserService>();
    userService.Setup(u => u.Exists(fullName)).Returns(true);
    userService.Setup(u => u.FromName(fullName)).Returns(joeUser.Object);

    var controller = new ApiController(userService.Object);

    // Act
    var result = controller.GetBOUser("extranet", "Joe", "password", new Login());

    // Assert
    Assert.AreEqual(fullName, result.Name);
}

另一件事...您的 GetBOUser 方法接受密码,但在返回用户之前不会验证它。 这对 API 的消费者来说是非常误导的。 如果您接受密码,则应在返回请求的用户对象之前确保密码正确。

© www.soinside.com 2019 - 2024. All rights reserved.