URL di test unitari URL.IsCalURL (returnurl.ToString ()), come posso farlo restituire falso nel test unitario?
-
13-11-2019 - |
Domanda
Dal metodo di accesso standard nel controller dell'account nelle applicazioni MVC3, come posso testare il
Url.IsLocalUrl(returnUrl.ToString())
riga di codice in cui l'URL non è locale? In altre parole, quale URL devo nutrire questa riga di codice durante il test unitario, per farlo restituire falso?
Ho usato il seguente pensiero che questo sarebbe restituito come falso (non locale):
Uri uri = new Uri(@"http://www.google.com/blahblah.html");
Ma ha appena lanciato un'eccezione nulla nei test dell'unità
EDIT: dovrei aggiungere che il metodo di accesso ora sembra così:
public ActionResult LogOn(LogOnModel model, System.Uri returnUrl)
if (ModelState.IsValid) {
bool loggedOn = LogOn(model);
if (loggedOn) {
if (Url.IsLocalUrl(returnUrl.ToString())) {
return Redirect(returnUrl.ToString());
}
else {
return RedirectToAction("Index", "Home");
}
}
else {
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(viewModel);
}
Alcuni errori di analisi COP/CODE di stile hanno costretto a modificare da un parametro stringa a System.uri Parameter ma è molto simile all'originale standard.
Solo per chiarire, in un test unitario - voglio testare e affermare il risultato di colpire il Else
linea dove reindirizza a Home/Index
, quindi ho bisogno di passare qualcosa per il (System.Uri)returnUrl
che lo farà restituire falso Url.IsLocalUrl
E non lanciare un'eccezione
Ulteriori modifiche:
Sto usando MVCContrib Testhelper, che è abbastanza bravo a deridere molte cose HTTPContext e Web:
Builder = new TestControllerBuilder();
UserController = new UserController();
Builder.InitializeController(UserController);
Soluzione
È necessario deridere l'istanza HTTPContext e Urlhelper sul controller che stai test. Ecco un esempio di come potrebbe apparire quel test unitario se stai usando Moq:
[TestMethod]
public void LogOn_Should_Redirect_To_Home_If_Authentication_Succeeds_But_Not_Local_ReturnUrl_Is_Provided()
{
// arrange
var sut = new AccountController();
var model = new LogOnModel();
var returnUrl = new Uri("http://www.google.com");
var httpContext = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
httpContext.Setup(x => x.Request).Returns(request.Object);
request.Setup(x => x.Url).Returns(new Uri("http://localhost:123"));
var requestContext = new RequestContext(httpContext.Object, new RouteData());
sut.Url = new UrlHelper(requestContext);
// act
var actual = sut.LogOn(model, returnUrl);
// assert
Assert.IsInstanceOfType(actual, typeof(RedirectToRouteResult));
var result = (RedirectToRouteResult)actual;
Assert.AreEqual("Home", result.RouteValues["controller"]);
Assert.AreEqual("Index", result.RouteValues["action"]);
}
Nota: da quando hai effettivamente mostrato il LogOn
Implementazione che stai chiamando per verificare le credenziali, potrebbe essere necessario adattare il test unitario per garantire che questo metodo restituisca vero in primo luogo dato il modello per inserire il if (loggedOn)
clausola.
AGGIORNARE:
Sembra che tu stia usando Mvccontrib.testhelper che fa tutta la configurazione di deridere HTTPContext per te. Quindi tutto ciò che devi fare è deridere le parti pertinenti per il test dell'unità:
[TestMethod]
public void LogOn_Should_Redirect_To_Home_If_Authentication_Succeeds_But_Not_Local_ReturnUrl_Is_Provided()
{
// arrange
var sut = new AccountController();
new TestControllerBuilder().InitializeController(sut);
var model = new LogOnModel();
var returnUrl = new Uri("http://www.google.com");
sut.HttpContext.Request.Expect(x => x.Url).Return(new Uri("http://localhost:123"));
// act
var actual = sut.LogOn(model, returnUrl);
// assert
actual
.AssertActionRedirect()
.ToController("Home")
.ToAction("Index");
}
Normalmente le prime 2 righe del test unitario potrebbero essere spostate nel globale [SetUp]
Metodo per evitare di ripeterli in ogni test dell'unità per questo controller in modo che ora il test diventi un po 'più pulito:
[TestMethod]
public void LogOn_Should_Redirect_To_Home_If_Authentication_Succeeds_But_Not_Local_ReturnUrl_Is_Provided()
{
// arrange
var model = new LogOnModel();
var returnUrl = new Uri("http://www.google.com");
_sut.HttpContext.Request.Expect(x => x.Url).Return(new Uri("http://localhost:123"));
// act
var actual = _sut.LogOn(model, returnUrl);
// assert
actual
.AssertActionRedirect()
.ToController("Home")
.ToAction("Index");
}