最小起订量单元测试 - 多个开机自检方法失败



我已经为 ASP.NET 核心MVC应用程序编写了单元测试用例。该函数具有多个发布方法和一个获取方法。第一个 Post 方法正确注入并成功通过测试,但是第二个 Post 方法始终为 NULL,并且不会成功注入,但前面的 Get & Post 操作成功。

此行未正确注入。

_WebService.Setup(test => test.PostRequestAsync<CommonResultDTO>(Constants.SendVerificationCodeAPI, customViewModel)).ReturnsAsync(deserialisedObj);

此调用的返回值始终为 null。

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);
}
}

请建议如何使其工作。

当设置中使用的参数与执行测试时传递的参数不匹配时,模拟将返回返回类型的默认值。在本例中为

如果参数的值无关紧要,则可以使用It.IsAny<T>()来放松匹配

_WebService
.Setup(_ => _.PostRequestAsync<CommonResultDTO>(Constants.SendVerificationCodeAPI, It.IsAny<CustomViewModel>()))
.ReturnsAsync(deserialisedObj);

最新更新