Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Microsoft Fakes进行模拟_C#_.net_Async Await_Microsoft Fakes - Fatal编程技术网

C# 使用Microsoft Fakes进行模拟

C# 使用Microsoft Fakes进行模拟,c#,.net,async-await,microsoft-fakes,C#,.net,Async Await,Microsoft Fakes,我用异步(.net 4.5)方法密封了需要模拟的类。我使用的是微软的赝品,所以它们将是“垫片”。下面的代码是我需要做的一个示例。它构建,但当运行并调用“Login”控制器方法中的“LoginAsync”方法时,测试挂起 [TestMethod] public async Task LoginPost_Returns() { using (ShimsContext.Create()) { var c = new TestController();

我用异步(.net 4.5)方法密封了需要模拟的类。我使用的是微软的赝品,所以它们将是“垫片”。下面的代码是我需要做的一个示例。它构建,但当运行并调用“Login”控制器方法中的“LoginAsync”方法时,测试挂起

  [TestMethod]
  public async Task LoginPost_Returns() {

     using (ShimsContext.Create()) {
        var c = new TestController();
        var user=new User();

        Fakes.ShimUserManager.AllInstances.LoginAsyncString = (um, u) => new Task<IUser>(() => { return user; });

        //call controller method  
        var result = await c.Login(model, returnUrl) as ViewResult;
        var expectedViewName = "Index";
        Assert.IsNotNull(result);
        Assert.AreEqual(expectedViewName, result.ViewName);
     }

//Controller method
public async Task<ActionResult> Login(LoginModel model, string returnUrl) {
     var user = await UserManager.LoginAsync(model.UserName, model.password);
     return View();
}
[TestMethod]
公共异步任务LoginPost_返回(){
使用(ShimsContext.Create()){
var c=新的TestController();
var user=新用户();
Fakes.ShimUserManager.AllInstances.LoginAsyncString=(um,u)=>新任务(()=>{return user;});
//调用控制器方法
var result=等待c.Login(model,returnUrl)作为ViewResult;
var expectedViewName=“Index”;
Assert.IsNotNull(结果);
Assert.AreEqual(expectedViewName、result.ViewName);
}
//控制器方法
公共异步任务登录(LoginModel模型,字符串返回URL){
var user=await UserManager.LoginAsync(model.UserName,model.password);
返回视图();
}

不要在
async
代码中使用
Task
构造函数。如果您只需要一个带返回值的已完成
任务,请使用
Task。FromResult

IUser user = new User();
Fakes.ShimUserManager.AllInstances.LoginAsyncString = (um, u) => Task.FromResult(user);
作为附加提示,最好在单元测试中涵盖这些情况:

  • 同步成功(
    Task.FromResult(用户)
  • 异步成功(
    Task.Run(()=>user)
  • 异步错误(
    Task.Run(()=>{抛出新的InvalidOperationException(“或其他”);返回用户;})

在这种错误情况下,显式指定委托类型难道不会比使用不可访问的
return
更清晰吗?任务从未开始的好观点。我一直在思考这些问题。对于第二点,LoginAsync方法(returns IUser)是业务层方法,而Login方法(returns ViewResult)是是一个控制器操作方法。它们不是同一个方法。@user2507103我想我现在明白了。我已经从我的答案中删除了关于类型的部分。我喜欢使lamdba异步的选项。然后还必须包括一个wait,这可能只是一个1毫秒的延迟,然后继续返回您想要返回的内容。使lambda异步模拟目标方法,该方法将被更紧密地填充,并且也将更容易让其他人理解。
Fakes.ShimUserManager.AllInstances.LoginAsyncString = async (um, u) => user;
IUser user = new User();
Fakes.ShimUserManager.AllInstances.LoginAsyncString = (um, u) => Task.FromResult(user);