我如何模拟一个UserPrincipal?

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

我想实际测试一次我的代码,但模拟一直是我的致命弱点之一。

我正在用AD做一些事情,想在不实际接触它的情况下进行测试。这就是我正在做的事情。

var userPrincipalMock = new Mock<UserPrincipal>();
userPrincipalMock.Setup(x => x.SamAccountName).Returns("somesamaccountname");
userPrincipalMock.Setup(x => x.EmployeeId).Returns("anemployeenumber");

但是... 显然 UserPrincipal不想轻易放弃对一个同名账户的控制。

Message "Unsupported expression: x => x.SamAccountName\nNon-overridable members (here: Principal.get_SamAccountName) may not be used in setup / verification expressions."

你们这些可爱的家伙或姑娘们有谁知道正确的方法吗?

c# unit-testing active-directory moq
1个回答
0
投票

不可能测试那些没有被标记为... virtual. 由于这个原因,应该只对接口进行嘲讽。为了解决你的问题,你可以创建一个包装器。

interface IUserPrincipalWrapper
{
    string SamAccountName { get; set; }
    string EmployeeId { get; set; }
    void Delete();
    ... // Add all methods and properties of UserPrincipal that you need
}
class UserPrincipalWrapper : IUserPrincipalWrapper
{
    private UserPrincipal Implementation { get; }

    UserPrincipalWrapper(UserPrincipal implementation)
    {
       Implementation = implementation;
    }

    public string SamAccountName
    { 
     get => Implementation.SamAccountName; 
     set => Implementation.SamAccountName = value;
    }

    public string EmployeeId 
    { 
     get => Implementation.EmployeeId; 
     set => Implementation.EmployeeId = value;
    }

    public void Delete()
    {
        Implementation.Delete();
    }
    ...
    // Call or set everything to Implementation...
    // This is needed to create an interface around UserPrincipal, which you can mock
}
// Factory is needed for mocking `new` calls..
// as often times, you don't want to test that either
interface IUserPrincipalFactory
{
  IUserPrincipalWrapper Create(PrincipalContext context);
}
class UserPrincipalFactory : IUserPrincipalFactory
{
  public IUserPrincipalWrapper Create(PrincipalContext context)
  {
    var implementation = new UserPrincipal(context);
    return new UserPrincipalWrapper(implementation);
  }
}

然后在你的测试中,你可以模拟所有的东西。

// This is your mock
var userPrincipalMock = new Mock<IUserPrincipalWrapper>();

// You need factory for mocking `new UserPrincipal();` calls
var factoryMock = new Mock<IUserPrincipalWrapperFactory>();
factoryMock.Setup(factory => factory.Create(It.IsAny<PrincipalContext>())).Returns(userPrincipalMock.Object);

// Now it works :)
userPrincipalMock.Setup(x => x.SamAccountName).Returns("somesamaccountname");
userPrincipalMock.Setup(x => x.EmployeeId).Returns("anemployeenumber");
© www.soinside.com 2019 - 2024. All rights reserved.