即使在使用 Moq 设置时发送正确数量的参数,也会获得 System.ArgumentException

Getting System.ArgumentException even while sending the right number of parameters while using Moq setup

在对我的 ASP.NET 网络 api 控制器进行单元测试时,对于我的一个 post 请求,我在 repo 函数中发送了两个参数,像往常一样我在模拟存储库设置,但即使我发送两个参数,我也会收到参数异常。

回购代码-

public async Task<TblUser> Register(TblUser user, string password)
    {
        byte[] passwordHash, passwordSalt;
        CreatePasswordHash(password, out passwordHash, out passwordSalt);
        user.APasswordHash = passwordHash;
        user.APasswordSalt = passwordSalt;
        await _context.TblUser.AddAsync(user);
        await _context.SaveChangesAsync();
        return user;
    }

控制器代码-

[HttpPost("register")]
    public async Task<IActionResult> Register(UserForRegisterDto userForRegisterDto)
    {
        userForRegisterDto.AUsername = userForRegisterDto.AUsername.ToLower();

        if (await _repo.UserExists(userForRegisterDto.AUsername))
            return BadRequest("username already exists");

        if(!ModelState.IsValid || userForRegisterDto.AUsername == null || userForRegisterDto.Password == null || userForRegisterDto.AEmail ==null || userForRegisterDto.Aname ==null)
        {
            return BadRequest("invalid user");
        }

        var userToCreate = _mapper.Map<TblUser>(userForRegisterDto);

        var createdUser = await _repo.Register(userToCreate, userForRegisterDto.Password);

        var userToReturn = _mapper.Map<UserForDetailedDto>(createdUser);

        return CreatedAtRoute("GetUser", new
        {
            controller = "Users",
            id = createdUser.ACustomerId
        }, userToReturn
        );
    }

控制器测试代码-

[Test]
    public async Task GivenAValidUser_WhenIRegisterANewUser_ThenItReturnsOkWithResponse()
    {
        _mockAuthRepository = new Mock<IAuthRepository>();
        _mockAuthMapper = new Mock<IMapper>();
        _mockConfig = new Mock<IConfiguration>();
        UserForRegisterDto expectedUser = new UserForRegisterDto
        {
            Aname = "Luffy",
            AUsername = "luffy",
            AEmail = "luffy@gmail.com",
            Password = "password",
            ADob = new DateTime(2000, 12, 12)
        };
        _mockAuthMapper.Setup(mapper => mapper.Map<TblUser>(It.IsAny<UserForRegisterDto>()))
            .Returns(new TblUser());
        _mockAuthMapper.Setup(mapper => mapper.Map<UserForDetailedDto>(It.IsAny<TblUser>()))
        .Returns(new UserForDetailedDto());
        _mockAuthRepository.Setup(repo => repo.Register(It.IsAny<TblUser>(), It.IsAny<string>()))
        .ReturnsAsync((TblUser user) => user);

        _authController = new AuthController(_mockAuthRepository.Object,_mockConfig.Object, _mockAuthMapper.Object);
        var tblUser = await _authController.Register(expectedUser);
        var okResult = tblUser as OkObjectResult;
        Assert.AreEqual(200, okResult.StatusCode);
        Assert.NotNull(okResult);
        Assert.IsAssignableFrom<OkObjectResult>(tblUser);
        var result = ((OkObjectResult)tblUser).Value;
        Assert.NotNull(result);
        Assert.AreEqual(expectedUser, result);
        Assert.IsAssignableFrom<TblUser>(result);


    }

异常由行抛出-

            _mockAuthRepository.Setup(repo => repo.Register(It.IsAny<TblUser>(), It.IsAny<string>()))
    .ReturnsAsync((TblUser user) => user);

如您所见,在设置模拟存储库时,我发送了两个参数,但出现了错误-

Message: 
System.ArgumentException : Invalid callback. Setup on method with 2 parameter(s) cannot invoke callback with different number of parameters (1).

堆栈跟踪:

<>c__DisplayClass22_0 
<SetReturnComputedValueBehavior>g__ValidateCallback|4(Delegate callback)
MethodCall.SetReturnComputedValueBehavior(Delegate valueFactory)
NonVoidSetupPhrase`2.Returns[T1](Func`2 valueExpression)
GeneratedReturnsExtensions.ReturnsAsync[T,TMock,TResult]
(IReturns`2 mock, Func`2 valueFunction) AuthControllerTests.GivenAValidUser_WhenIRegisterANewUser_ThenItReturnsOkWithResponse() line 43
GenericAdapter`1.GetResult()
AsyncToSyncAdapter.Await(Func`1 invoke)
TestMethodCommand.RunTestMethod(TestExecutionContext context)
TestMethodCommand.Execute(TestExecutionContext context)
SimpleWorkItem.PerformWork()

我是单元测试的新手,但到目前为止,我对 GET 和 POST 请求的单元测试一直以这种方式运行良好。这是我在内部调用的哈希函数的问题吗?

正在运行的控制器代码- [允许匿名] [HttpPost()] public 异步任务 AddMovie(MovieForDetailedDto movieForDetailedDto) { 如果(等待_repo.MovieExists(movieForDetailedDto.ATitle)) return BadRequest("电影已经存在");

        else if(!ModelState.IsValid || movieForDetailedDto.ATitle == null || movieForDetailedDto.APrice == null || movieForDetailedDto.AMovieDescription ==null)
        {
            return BadRequest("movie details not valid");
        }

        var movieToCreate = _mapper.Map<TblMovie>(movieForDetailedDto);

        var createdMovie = await _repo.AddMovie(movieToCreate);

        return Ok(createdMovie);
    }

适用于上述控制器的测试-

        [Test]
    public async Task GivenAValidMovie_WhenIPostANewMovie_ThenItReturnsOkWithResponse()
    {
        _mockMovieRepository = new Mock<IMovieRepository>();
        _mockMovieMapper = new Mock<IMapper>();
        TblMovie expectedMovie = new TblMovie
        {
            AMovieId = 55,
            ATitle = "redemption",
            AMovieDescription = "An action comedy adventure about brilliant robotics prodigy Hiro Hamada, who finds himself in the grips of a criminal plot that threatens to destroy the fast-paced, high-tech city of San Fransokyo. With the help of his closest companion-a robot named Baymax-Hiro joins forces with a reluctant team of first-time crime fighters on a mission to save their city.",
            ADuration = "105 min",
            APrice = "10",
            APurchasePrice = "25",
            ARating = 5,
            AImageLink = "http://upload.wikimedia.org/wikipedia/en/4/4b/Big_Hero_6_%28film%29_poster.jpg",
            ATrailerLink = "//www.youtube.com/embed/z3biFxZIJOQ",
            AGenre = "Comedy",
            AWideImage = "https://github.com/tushar23091998/MovieRentalApp-FrontEnd/blob/master/src/app/images/bighero6.jpg?raw=true"
        };
        _mockMovieMapper.Setup(mapper => mapper.Map<TblMovie>(It.IsAny<MovieForDetailedDto>()))
            .Returns(expectedMovie);
        _mockMovieRepository.Setup(repo => repo.AddMovie(It.IsAny<TblMovie>()))
            .ReturnsAsync((TblMovie movie) => movie);

        _moviesController = new MoviesController(_mockMovieRepository.Object, _mockMovieMapper.Object);
        var tblMovie = await _moviesController.AddMovie(new MovieForDetailedDto
        {
            AMovieId = 55,
            ATitle = "redemption",
            AMovieDescription = "An action comedy adventure about brilliant robotics prodigy Hiro Hamada, who finds himself in the grips of a criminal plot that threatens to destroy the fast-paced, high-tech city of San Fransokyo. With the help of his closest companion-a robot named Baymax-Hiro joins forces with a reluctant team of first-time crime fighters on a mission to save their city.",
            ADuration = "105 min",
            APrice = "10",
            APurchasePrice = "25",
            ARating = 5,
            AImageLink = "http://upload.wikimedia.org/wikipedia/en/4/4b/Big_Hero_6_%28film%29_poster.jpg",
            ATrailerLink = "//www.youtube.com/embed/z3biFxZIJOQ",
            AGenre = "Comedy",
            AWideImage = "https://github.com/tushar23091998/MovieRentalApp-FrontEnd/blob/master/src/app/images/bighero6.jpg?raw=true"
        });
        var okResult = tblMovie as OkObjectResult;
        Assert.AreEqual(200, okResult.StatusCode);
        Assert.NotNull(okResult);
        Assert.IsAssignableFrom<OkObjectResult>(tblMovie);
        var result = ((OkObjectResult)tblMovie).Value;
        Assert.NotNull(result);
        Assert.AreEqual(expectedMovie,result);
        Assert.IsAssignableFrom<TblMovie>(result);


    }

所以我以前只接受一个参数的 repo 函数工作正常。

感谢您的宝贵时间。如果答案太明显,我们深表歉意。

.ReturnsAsync((TblUser user) =>

只有一个参数。这应该是

.ReturnsAsync((TblUser user, string password) =>