繁体   English   中英

嘲笑UserPrincipal

[英]Mocking UserPrincipal

我有一个类来处理密码更改和交换邮箱的到期检查。 我在UserPrincipal上检查LastPasswordSet。

那TDD怎么样?

我想通过编写一些测试来检查我的类是否正确处理了密码检查。 但我无法理解我如何模拟UserPrincipal.FindByIdentity(principalContext,[some username])。

如果密码在过去90天内被更改,我即将编写一个返回true / false的方法。 所以我想模拟UserPrincipal,这样我就可以在我的测试中设置LastPasswordSet返回值,只是为了检查我要编写的“密码需求更改通知”的逻辑。

我意识到这是一个老帖子,但最近我遇到了与原始海报相同的问题,在看完答案之后,我想我必须做同样的事情。 我不希望别人读这篇文章,像我一样浪费宝贵的时间,所以我决定真正回答这篇文章。

在意识到没有简单的方法来包装UserPrincipal功能,也不依赖于像建议的集成或端到端测试之后,我记得有一种模拟静态类的方法。 话虽如此,下面是使用Telerik JustMock的确切方法

private void MockUserPrincipal()
    {
        //Mock principal context
        var context = Mock.Create<PrincipalContext>((action) => action.MockConstructor());

        //Mock user principal
        var user = Mock.Create(() => new UserPrincipal(context));           

        //Mock the properties you need
        Mock.Arrange(() => user.Enabled).Returns(true);
        Mock.Arrange(() => user.UserPrincipalName).Returns("TestUser");
        Mock.Arrange(() => user.LastPasswordSet).Returns(DateTime.Now);

        //Mock any functions you need
        Mock.Arrange(() => user.IsAccountLockedOut()).Returns(false);

        //Setup static UserPrincipal class
        Mock.SetupStatic<UserPrincipal>();

        //Mock the static function you need
        Mock.Arrange(() => UserPrincipal.FindByIdentity(Arg.IsAny<PrincipalContext>(), Arg.AnyString)).Returns(user);  

        //Now calling UserPrincipal.FindByIdentity with any context and identity will return the mocked UserPrincipal
    }

我会用精辟的短语回答这个问题

“不要嘲笑你不拥有的类型”

无法找到一个权威的博客来支持这一点。 示例链接 虽然它似乎归功于Joe Walnes。

UserPrincipal如果我记得是一个与身份验证相关的.Net框架类。 模拟不受您控制(可能更改)的类型可能导致脆弱的测试。

而是从UserPrincipal发现您的设计需要什么

  • 通过TDDing客户端找到UserPrincipal间接实现或实现的角色
  • 在你的单元中模拟该角色测试并测试所有呼叫者。
  • 进行“集成测试”以确保您的实际实现在调用时在UserPrincipal上按下正确的按钮。
  • 依靠端到端/验收测试来查找所有组件串在一起时发生的错误。

老帖但有一个有效的例子。 即使你从不测试别人的代码,你也想测试你的方法。 并且您的方法可能需要来自另一个方法返回的UserPrincipal数据。 现在说你需要检查LastPasswordSet属性。

  1. 右键单击单元测试项目中的.dll System.DirectoryServices.AccountManagement 选择“添加假装配”。
  2. 添加此单元测试

     [TestMethod] public async Task ActiveDirectoryUserFactory_CreateUserAsyncAndWhatYouExpect() { // Arrange using(ShimsContext.Create()) { var userPrincipal = new System.DirectoryServices.AccountManagement.Fakes.ShimUserPrincipal(); var baseUserPrincipal = new System.DirectoryServices.AccountManagement.Fakes.ShimAuthenticablePrincipal(userPrincipal); baseUserPrincipal.LastPasswordSetGet = () => DateTime.Now; // Mock the returned UserPrincipal to use our userPrincipal, here's for Moq _class.Setup(x => x.GetUserAsync("param")) .Returns(Task.FromResult<UserPrincipal>(userPrincipal)); // Act, your method that gets your shimUserPrincipal from _class.GetUserAsync in your _target class (I understood you got the UserPrincipal from external source) var user = await _target.YourMethod(); // Assert Assert.IsNull(user); } } // method that does the code you want to test public async Task<Object> YourMethod() { var user = await _class.GetUserAsync("param"); var lastLogin = user.LastPasswordSet; return new Object() } 

Shims有很多资源,所以我让它像这样。 希望这可以帮助谷歌搜索“模拟UserPrincipal”的人。

我担心UserPrincipal类不是TDD友好的。
如何将您需要的功能包装在您的类中并进行模拟呢?

暂无
暂无

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

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