C# 模仿用户主体
我有一个类处理exchange邮箱的密码更改和过期检查。 我在UserPrincipal上检查LastPasswordSet 那么TDD呢 我想通过编写一些测试来检查我的类是否正确处理了密码检查。但是我无法理解我如何能够嘲笑UserPrincipal.FindByIdentity(principalContext,[some username])C# 模仿用户主体,c#,.net,tdd,C#,.net,Tdd,我有一个类处理exchange邮箱的密码更改和过期检查。 我在UserPrincipal上检查LastPasswordSet 那么TDD呢 我想通过编写一些测试来检查我的类是否正确处理了密码检查。但是我无法理解我如何能够嘲笑UserPrincipal.FindByIdentity(principalContext,[some username]) 我将要编写一个方法,如果在过去90天内更改了密码,该方法将返回true/false。所以我想模拟UserPrincipal,这样我就可以在测试中设置L
我将要编写一个方法,如果在过去90天内更改了密码,该方法将返回true/false。所以我想模拟UserPrincipal,这样我就可以在测试中设置LastPasswordSet返回值,只是为了检查我将要为“密码需要更改通知”编写的逻辑。恐怕UserPrincipal类不是真正的TDD友好类。
把你需要的功能包装到你的类中,然后模仿它怎么样?我将用一个简洁的短语来回答这个问题 “不要嘲笑你没有的类型” 找不到权威的博客帖子来支持。虽然这似乎是乔·沃恩斯的功劳 如果我记得的话,UserPrincipal是一个与身份验证相关的.Net framework类。无法控制(可以更改)的模拟类型可能会导致脆弱的测试 相反,从UserPrincipal中发现您的设计想要什么
- 查找UserPrincipal通过tding客户端间接履行或实现的角色
- 在单元测试中模拟该角色并测试所有调用者
- 进行“集成测试”,以确保您的实际实现在调用UserPrincipal时按正确的按钮
- 依靠端到端/验收测试来发现所有组件串在一起时出现的错误
private void MockUserPrincipal()
{
//模拟主体上下文
var context=Mock.Create((action)=>action.MockConstructor());
//模拟用户主体
var user=Mock.Create(()=>newuserprincipal(context));
//模拟你需要的属性
Mock.Arrange(()=>user.Enabled)。返回(true);
Mock.Arrange(()=>user.UserPrincipalName).Returns(“TestUser”);
Mock.Arrange(()=>user.LastPasswordSet).Returns(DateTime.Now);
//模拟您需要的任何函数
Mock.Arrange(()=>user.IsAccountLockedOut()).Returns(false);
//设置静态UserPrincipal类
Mock.SetupStatic();
//模拟所需的静态函数
Mock.Arrange(()=>UserPrincipal.FindByIdentity(Arg.IsAny(),Arg.AnyString)).Returns(user);
//现在,使用任何上下文和标识调用UserPrincipal.FindByIdentity将返回模拟的UserPrincipal
}
这篇文章很旧,但有一个有效的例子。即使您永远不应该测试其他人的代码,但您希望测试您的方法。您的方法可能需要来自另一个方法返回的UserPrincipal
的数据。现在假设您需要检查LastPasswordSet
属性
System.DirectoryServices.AccountManagement
。选择“添加假货组件”[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()
}
[TestMethod]
公共异步任务ActiveDirectoryUserFactory\u CreateUserAsyncAndWhatYouExpect()
{
//安排
使用(ShimsContext.Create())
{
var userPrincipal=new System.DirectoryServices.AccountManagement.Fakes.ShimUserPrincipal();
var baseUserPrincipal=new System.DirectoryServices.AccountManagement.Fakes.ShimAuthenticatablePrincipal(userPrincipal);
baseUserPrincipal.LastPasswordSetGet=()=>DateTime.Now;
//模拟返回的UserPrincipal以使用我们的UserPrincipal,这里是Moq
_Setup(x=>x.GetUserAsync(“param”))
.Returns(Task.FromResult(userPrincipal));
//Act,从_目标类中的_class.GetUserAsync获取shimUserPrincipal的方法(我知道您是从外部源获取UserPrincipal的)
var user=wait_target.YourMethod();
//断言
Assert.IsNull(用户);
}
}
//方法,该方法执行要测试的代码
公共异步任务方法()
{
var user=await_class.GetUserAsync(“param”);
var lastLogin=user.LastPasswordSet;
返回新对象()
}
垫片有很多来源,所以我就让它变成这样。希望这能帮助那些在谷歌上搜索“mock UserPrincipal”的人。是的,我已经考虑过了,最后可能会得到一个userprincipalwrapperHelper提示:-)您需要Visual Studio Enterprise edition来启用文档中所述的假程序集:
[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()
}