Learning MSTest -- trying to unit test a REST function: AccountController (which I believe will work) I want to start with Register. I can't get the Mocks setup for some reason. (Moq is installed). Also, I'm confused as to how this could possibly be of any use; if I mock all the controller inputs, I'm not going to get anything back? Your Advice?
AccountController - target of the unit test:
namespace API.Controllers
{
public class AccountController : BaseApiController
{
private readonly UserManager<AppUser> _userManager;
private readonly SignInManager<AppUser> _signInManager;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly ITokenService _tokenService;
private readonly IMapper _mapper;
public AccountController(
UserManager<AppUser> userManager,
SignInManager<AppUser> signInManager,
RoleManager<IdentityRole> roleManager,
ITokenService tokenService,
IMapper mapper)
{
_signInManager = signInManager;
_roleManager = roleManager;
_mapper = mapper;
_tokenService = tokenService;
_userManager = userManager;
}
[HttpPost("register")]
// [Authorize]
[Authorize(Roles = "Admin")]
public async Task<ActionResult<UserDto>> Register(RegisterDto registerDto)
{
if (await this.UserExistsAsync(registerDto.Username)) return BadRequest("Username is taken");
var user = _mapper.Map<AppUser>(registerDto);
user.UserName = registerDto.Username.ToLower();
var result = await _userManager.CreateAsync(user, registerDto.Password);
if (!result.Succeeded) return BadRequest(result.Errors);
var roleResult = await _userManager.AddToRoleAsync(user, "User");
if (!roleResult.Succeeded) return BadRequest(result.Errors);
return new UserDto
{
Username = user.UserName,
Token = await _tokenService.CreateToken(user),
KnownAs = user.KnownAs
};
}
BTW BaseController is simply:
{
[ApiController]
[Route("api/[controller]")]
public class BaseApiController : ControllerBase
{
}
}
The Unit Test so far is:
namespace API.Controllers.Tests
{
[TestClass()]
public class AccountControllerTests
{
[TestMethod()]
public async void AccountController_Register()
{
var _userManager = new Mock<UserManager<AppUser>>();
var _signInManager = new Mock<SignInManager<AppUser>>();
var _roleManager = new Mock<RoleManager<IdentityRole>>();
ITokenService tokenService;
IMapper mapper;
RegisterDto userDto = new RegisterDto()
{
Username = "Admin",
Password = "Secret1234",
FirstName = "Johnny",
LastName = "Appleseed",
Phone1 = "6175551212",
Phone2 = "",
KnownAs = "Dude",
EmailAddress = "Dude@Somewhere.com",
Question = "ask",
Answer = "answer",
};
AccountController accountController = new AccountController(_userManager,
_signInManager,
_roleManager,
tokenService,
mapper);
await accountController.Register(userDto);
Assert.Fail(); <<---- this will be replaced obviously
}
The compiler error looks like this:
Other arguments have a similar error message.
Your Advice OR point me to a tutorial somewhere that covers MSTest Mocks :-) Thanks in advance.
Chuck
For Mock<T>
you need to call .Object
to get the mocked type
AccountController accountController =
new AccountController(_userManager.Object, //<-- NOTE ".Object" on Mock<T>
_signInManager.Object,
_roleManager.Object,
tokenService,
mapper);
Also you will need to setup the expected behavior using .Setup
so that the mock behave as expected when the subject under test is being exercised.
Reference Moq Quickstart to get an idea of how to actually use the library