C# 模拟签名管理器未按预期工作

C# 模拟签名管理器未按预期工作,c#,asp.net-core-mvc,moq,identity,razor-pages,C#,Asp.net Core Mvc,Moq,Identity,Razor Pages,我正在模拟asp.net标识的登录过程,令我惊讶的是\u mockSignInManager.Setup( x=>x.PasswordSignInAsync(It.IsAny(),It.IsAny(),It.IsAny(),It.IsAny()).ReturnsAsync(SignInResult.Success) 不返回SignInResult.Success。在下面的代码中,我将显示var result返回null并中断程序。这对我来说很奇怪,因为带有UserManager的CreateAs

我正在模拟asp.net标识的登录过程,令我惊讶的是
\u mockSignInManager.Setup(
x=>x.PasswordSignInAsync(It.IsAny(),It.IsAny(),It.IsAny(),It.IsAny()).ReturnsAsync(SignInResult.Success)
不返回
SignInResult.Success
。在下面的代码中,我将显示
var result
返回
null
并中断程序。这对我来说很奇怪,因为带有UserManager的
CreateAsync()
返回
Task
,而这个
PasswordSignInAsync()
返回
Task
。然而,其他的测试工作正常,而这却不行。代码如下:

LoginModelTests
[TestFixture]
公共类LoginModelTests
{
私有模拟(mockSignInManager);;
私有Mock\u mockInputModel;
[设置]
公共作废设置()
{
_mockSignInManager=new Mock();
_mockInputModel=new Mock();
SetUpFakeSignInManager();
}
[测试]
PostAsync_StateUnderTest_ExpectedBehavior()上的公共异步任务
{
//安排
var unitUnderTest=new LoginModel(_mockSignInManager.Object,_mockInputModel.Object);
//表演
var result=await unitUnderTest.OnPostAsync(“/asdsad/asda”);
var okResult=结果为OkObjectResult;
//断言
if(okResult!=null&&okResult.StatusCode==200)
Assert.Pass();
}
私有void SetUpFakeSignInManager()
{
_mockSignInManager.Setup(
x=>x.PasswordSignInAsync(It.IsAny(),It.IsAny(),It.IsAny(),
返回(Task.FromResult(SignInResult.Success));
}
登录模型
public类LoginModel:PageModel
{
专用只读签名管理器\u签名管理器;
公共登录模型(SignInManager SignInManager、InputModel InputModel)
{
_signInManager=signInManager;
输入=输入模型;
}
[BindProperty]
公共输入模型输入{get;set;}
公共异步任务OnPostAsync(字符串returnUrl=null)
{
returnUrl=returnUrl??Url.Content(“~/”);
if(ModelState.IsValid)
{
var result=wait _signInManager.PasswordSignInAsync(Input.Email、Input.Password、Input.RememberMe、lockoutOnFailure:false);
if(result.successed)
{
_logger.LogInformation(“用户登录”);
返回LocalRedirect(returnUrl);
}
}
返回页();
}
}
您为测试设置的和在测试方法中调用的具有不同的签名

所以你设置了错误的方法

更新设置

_mockSignInManager.Setup(
    x => x.PasswordSignInAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(),
        It.IsAny<bool>())).Returns(Task.FromResult(SignInResult.Success));
\u mockSignInManager.Setup(
x=>x.PasswordSignInAsync(It.IsAny(),It.IsAny(),It.IsAny(),
返回(Task.FromResult(SignInResult.Success));

PasswordSignInAsync
您为测试设置的和在被测试方法中调用的有不同的签名。是的!!!谢谢@Nkosi。不敢相信我错过了,所有测试都成功通过了:)您知道如果一个方法中有许多
if
语句,我如何测试它吗?提前谢谢@steve,这取决于方法的定义,因为有许多不同的方法来实现它。例如,上面的
if(result.Suceeded)
还有另外两个if,为了简单起见,我省略了它们。比如说还有其他条件,比如
if(result.requiretwofactor)
我该如何解释呢?@steve编写了另一个测试,其中模拟返回所需的条件,允许代码按预期流动/行为
public class LoginModel : PageModel
{
    private readonly SignInManager<IdentityUser> _signInManager;

    public LoginModel(SignInManager<IdentityUser> signInManager, InputModel inputModel)
    {
        _signInManager = signInManager;
        Input = inputModel;
    }

    [BindProperty]
    public InputModel Input { get; set; }

    public async Task<IActionResult> OnPostAsync(string returnUrl = null)
    {
        returnUrl = returnUrl ?? Url.Content("~/");

        if (ModelState.IsValid)
        {
            var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                _logger.LogInformation("User logged in.");
                return LocalRedirect(returnUrl);
            }
        }
        return Page();
    }
}
_mockSignInManager.Setup(
    x => x.PasswordSignInAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(),
        It.IsAny<bool>())).Returns(Task.FromResult(SignInResult.Success));