Я написал тестовый блок для приложения ASP.NET CORE MVC. Функция имеет метод нескольких записей и один метод Get. 1-й метод Post вводит корректно и тест успешно проходит, однако второй метод Post всегда имеет значение NULL и не вводит успешно, но предыдущая операция Get & Post прошла успешно.
Эта строка вводится неправильно.
_WebService.Setup(test => test.PostRequestAsync<CommonResultDTO>(Constants.SendVerificationCodeAPI, customViewModel)).ReturnsAsync(deserialisedObj);
Возвращаемое значение этого вызова всегда равно нулю.
var externalApiOutput = await _webService.PostRequestAsync<CommonResultDTO>(Constants.SendVerificationCodeAPI, newModel); // this value is returning null
Контроллер MVC
public class AccountController
{
private readonly IHttpContextAccessor _accessor;
public AccountController(IHttpContextAccessor accessor
, IWebService webService)
{
_accessor = accessor;
_webService = webService;
}
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
if (ModelState.IsValid)
{
model.Email = !string.IsNullOrEmpty(model.Email) ? model.Email.ToLowerInvariant() : string.Empty;
var result = await _webService.PostRequestAsync<CommonResultDTO>(Constants.UserLoginAPI, model);
if (result.Succeeded)
{
var output = JsonConvert.DeserializeObject<UserDto>(result.Object.ToString());
if (output != null && !string.IsNullOrEmpty(output.Email))
{
var userRoleInfo = await _webService.GetRequestAsync<List<UserRoleViewModel>>(string.Format(Constants.GetUserRoleInfoAPI, output.Email));
if (userRoleInfo != null)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, output.Email),
new Claim("Username", output.UserName),
new Claim(ClaimTypes.Role, Convert.ToString(userRoleInfo.FirstOrDefault().Name))
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties { IsPersistent = model.RememberMe });
if (output.TwoFactorEnabled)
{
var newModel = sendVerificationCode(output.PhoneNumber, Constants.CountryCodeValue);
var externalApiOutput = await _webService.PostRequestAsync<CommonResultDTO>(Constants.SendVerificationCodeAPI, newModel); // this value is returning null
// value of "externalApiOutput " is null, hence the further cases are failing.
if (externalApiOutput != null && externalApiOutput.Succeeded == true)
{
return RedirectToAction("Login_2FA");
}
}
else
{
return RedirectToAction("Dashboard", "Home");
}
}
}
return View(new LoginViewModel());
}
else
{
ShowMessage(MessageType.warning.ToString(), Constants.InvalidCredential);
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
private CustomViewModel sendVerificationCode(string toPhoneNumber, string countryCode)
{
var externalModel = new CustomViewModel();
ExternalAPIService externalService = new ExternalAPIService(_settings);
externalModel = externalService.GetOtherSettings();
externalModel.ToPhoneNumber = toPhoneNumber;
externalModel.CountryCode = countryCode;
return externalModel;
}
}
Модульный тест
public class AccountControllerTest : TestFixture
{
public AccountControllerTest()
{
_accessor = new Mock<IHttpContextAccessor>();
_WebService = new Mock<IWebService>();
var authServiceMock = new Mock<IAuthenticationService>();
authServiceMock
.Setup(_ => _.SignInAsync(It.IsAny<HttpContext>(), It.IsAny<string>(), It.IsAny<ClaimsPrincipal>(), It.IsAny<AuthenticationProperties>()))
.Returns(Task.FromResult((object)null));
var serviceProviderMock = new Mock<IServiceProvider>();
serviceProviderMock
.Setup(_ => _.GetService(typeof(IAuthenticationService)))
.Returns(authServiceMock.Object);
var urlHelperFactory = new Mock<IUrlHelperFactory>();
serviceProviderMock
.Setup(s => s.GetService(typeof(IUrlHelperFactory)))
.Returns(urlHelperFactory.Object);
var context = new DefaultHttpContext() {
RequestServices = serviceProviderMock.Object
};
_accessor.Setup(_ => _.HttpContext).Returns(context);
Mock<ITempDataDictionary> tempData = new Mock<ITempDataDictionary>();
accountController = new AccountController(_accessor.Object, _WebService.Object)
{
ControllerContext = new ControllerContext
{
HttpContext = new DefaultHttpContext
{
// How mock RequestServices?
RequestServices = serviceProviderMock.Object
}
}
, TempData =tempData.Object
};
}
[Fact]
public async Task LoginTest_Post_UserHasValidCredentialsAndRoleAndTwoFactor() // this method is failing, hence commented out for time-being
{
// Arrange
var mockModel = new LoginViewModel { };
mockModel.Email = "test@test.com";
mockModel.Password = "test123";
mockModel.RememberMe = false;
var customViewModel = new CustomViewModel()
{
ToPhoneNumber = "7009529018",
CountryCode = "91"
};
var commonResult = new CommonResultDTO { Object = User(), Succeeded = true, StatusCode = Common.Enums.ResponseStatusCodeEnum.Success };
var email = User().Email;
string stringObj = JsonConvert.SerializeObject(commonResult);
var deserialisedObj = JsonConvert.DeserializeObject<CommonResultDTO>(stringObj);
var output = GetUserRole();
_WebService.Setup(test => test.PostRequestAsync<CommonResultDTO>(Constants.UserLoginAPI, mockModel)).ReturnsAsync(deserialisedObj);
_WebService.Setup(test => test.GetRequestAsync<List<UserRoleViewModel>>(string.Format(Constants.GetUserRoleInfoAPI, email))).ReturnsAsync(output);
// this method is not injecting correctly and the value is alwasy NULL
_WebService.Setup(test => test.PostRequestAsync<CommonResultDTO>(Constants.SendVerificationCodeAPI, customViewModel)).ReturnsAsync(deserialisedObj);
var result = await accountController.Login(mockModel);
var redirectResult = result as RedirectToActionResult;
Assert.NotNull(redirectResult);
Assert.Equal("Home", redirectResult.ControllerName);
Assert.Equal("Dashboard", redirectResult.ActionName);
}
}
Пожалуйста, предложите, как это работает.