2016-11-07 5 views
1

Ich habe einen ASP.NET MVC 5-Controller mit der folgenden return-Anweisung:Wie man an ein Modell gelangt, das an RedirectToAction für Unit Test übergeben wurde?

return RedirectToAction("SendEmail",message); 

Wo Nachricht ein Objekt vom Typ der Nachricht ist. Ich möchte Einheit testen, dass dieser Controller das Nachrichtenobjekt ordnungsgemäß zurückgibt, nicht nur, dass es zur SendEmail-Aktion zurückkehrt (ich habe diesen Test bereits erfolgreich geschrieben).

Wie kann ich überprüfen, ob der Controller ein Message-Objekt ordnungsgemäß als Argument an RedirectToAction zurückgibt? Ich bin es zu erhalten, indem einfach versuchen, nicht in der Lage:

var result = controller.Save(mockMessage) as RedirectToRouteResult; 

//Assert 
Assert.IsInstanceOf<Message>(result.RouteValues); 

Ich bin vertraut mit Routevalues ​​[ „action“] und Routevalues ​​[ „Controller“], aber ich habe keine Ahnung, wie für ein Modell zu prüfen, das Ergebnis. RouteValues ​​["model"] funktioniert nicht so.

Voll Controller-Code:

public ActionResult Save([Bind(Exclude = "Id")] Message message) 
{ 

    if (!ModelState.IsValid) 
    { 
     var viewModel = new MessageViewModel(message); 
     return View("index",viewModel); 
    } 

    message.TimeStamp = DateTime.UtcNow; 
    _messageRepository.Add(message); 
    return RedirectToAction("SendEmail",message); 
} 
+1

Das zweite Argument von 'RedirectToAction' wird intern in' RouteValueDictionary' konvertiert. Der einzige Grund, warum Sie "Objekt" akzeptieren, ist, dass Sie Routing-Werte in einem praktischen 'neuen {k = v}' - Format definieren können. Ich denke nicht, dass Ihre 'Nachricht' in' RouteValueDictionary' konvertiert werden kann und am Ende ein 'RouteValueDictionary' ist, das den Eigenschaftsnamen und Werten Ihrer' Nachricht' entspricht. – haim770

+1

Ist die Save-Methode eine POST-Anfrage? Weil RedirectToAction eine GET-Anfrage erzeugt. –

+0

@AndriyTolstoy ja ist es. Danke für diese Anzeige. –

Antwort

1

Wenn Sie die Moq Framework verwenden Sie eine virtuelle Methode in der Controller-Klasse definieren, die die base.RedirectToAction nennt

public virtual RedirectToRouteResult RedirectToAction(string actionName, Message message) 
    { 
     return base.RedirectToAction(actionName, message); 
    } 

Diese Ihr Test sein könnte code:

[Test] 
    public void it_should_do() 
    { 
     var myController = new Mock<MyController> { CallBase = true }; 
     myController.Save(myMessage); 

     myController.Verify(m => m.RedirectToRouteResult(It.IsAny<string>(), It.IsAny<Message>()), Times.Once); 
     myController.Verify(m => m.RedirectToRouteResult("SendEmail", myMessage), Times.Once); 
    } 

Dies hat jedoch den Nachteil einer öffentlichen virtuellen Methode, aber Sie können testen, ob das Message-Objekt verwendet wird.

Verwandte Themen