2013-10-14 27 views
5

Also schreibe ich Tests für unsere MVC4-Anwendung und ich testen Controller-Aktionen speziell. Wie ich im Titel erwähne, trifft der Test immer noch den Dienst (WCF), anstatt Testdaten zurückzugeben. Ich habe diesen Controller:Gespiegelte Objekt immer noch Anrufe an Service

public class FormController : Controller 
{ 
    public SurveyServiceClient Service { get; set; } 
    public SurveyDao Dao { get; set; } 

    public FormController(SurveyServiceClient service = null, SurveyDao dao = null) 
    { 
     this.Service = service ?? new SurveyServiceClient(); 
     this.Dao = dao ?? new SurveyDao(Service); 
    } 

    // 
    // GET: /Form/ 

    public ActionResult Index() 
    { 
     var formsList = new List<FormDataTransformContainer>(); 
     Dao.GetForms().ForEach(form => formsList.Add(form.ToContainer())); 

     var model = new IndexViewModel(){forms = formsList}; 
     return View("Index", model); 
    } 

Und es nutzt dieses DAO-Objekt:

public class SurveyDao 
{ 
    private readonly SurveyServiceClient _service; 
    private readonly string _authKey; 

    public SurveyDao(SurveyServiceClient serviceClient) 
    { 
     _service = serviceClient; 
    } 

    .... 

    public FormContract[] GetForms() 
    { 
     var forms = _service.RetrieveAllForms(); 
     return forms; 
    } 

Und das ist mein Test mit JustMock, das Mock auf GetForms() gibt einige Testdaten in einer Hilfsklasse:

Mein Problem ist, dass der Dienst immer noch aufgerufen wird, wenn ich den Test ausführe. Ich habe dies mit Fiddler verifiziert und debugge den Test und prüfe den Wert von "result", der mit den Testdaten unseres Dienstes gefüllt ist.

EDIT:

ich den Test-Konstruktor geändert haben eine [TestInitialize] Funktion zu sein, so dass nun der Test wie folgt aussieht:

[TestClass] 
public class FormControllerTest 
{ 
    private SurveyDao mockDao; 
    private SurveyServiceClient mockClient; 

    [TestInitialize] 
    public void Initialize() 
    { 
     mockClient = Mock.Create<SurveyServiceClient>(); 
     mockDao = Mock.Create<SurveyDao>(Behavior.Strict); 
    } 

    [TestMethod] 
    public void TestIndexAction() 
    { 
     //Arrange 
     var controller = new FormController(mockClient, mockDao); 
     Mock.Arrange(() => mockDao.GetForms()).Returns(TestHelpers.FormContractArrayHelper); 

     //Act 
     var result = controller.Index() as ViewResult; 

     //Assert 
     Assert.IsInstanceOfType(result.Model, typeof(IndexViewModel)); 
    } 
} 
+1

Sollten GetForms keine virtuelle Methode sein? – rla4

+0

@ rla4, warum sagst du das? Müssen gespottete Methoden virtuell sein? – mam8cc

+1

Es kommt darauf an. Ich bin mit JustMock nicht vertraut, aber viele spöttische Frameworks verlassen sich auf Dynamix-Proxying, was virtuelle Methoden erfordern könnte :) – rla4

Antwort

3

Bitte überprüfen Sie, ob Sie die richtige Baugruppe für JustMock verwenden. Es gibt ein paar verschiedene (VisualBasic, Silverlight, JustMock).Der JustMock ist derjenige, den Sie in Ihr Projekt aufnehmen sollten.

Wenn Sie nicht den richtigen Code eingeben, wird das Verhalten verursacht, das Sie beschreiben (die Methode wird nicht korrekt ausgeführt).

1

Die JustMock manual (Highlights von mir) erklärt :

standardmäßig Telerik JustMock verwendet lose Mocks und ermöglicht es Ihnen,anrufeneine beliebige Methode für einen bestimmten Typ. Egal ob der Methodenaufruf angeordnet ist oder nicht Sie können es anrufen.

können Sie dieses Verhalten steuern, wenn die Create() Methode Sie Mock Aufruf:

var foo = Mock.Create<IFoo>(Behavior.Strict); 

Dort können Sie festlegen, was das Mock-Objekt tun sollten, wenn Sie nicht ausdrücklich eine bestimmte Methode implementiert. In Ihrem Fall (ich denke, es ist das Standardverhalten) ruft der Mock tatsächlich die ursprüngliche Methode für das Objekt auf, das Sie vortäuschen möchten.

Sie haben folgende Auswahlmöglichkeiten in der Behavior Enumeration Aufzählung:

  • Los: Legt fest, dass standardmäßig mock Anrufe wie ein Stummel verhalten werden, sofern nicht explizit Setup.
  • RecursiveLoose: Gibt an, dass Mock-Aufrufe standardmäßig Mock-Objekte zurückgeben, sofern sie nicht explizit eingerichtet wurden.
  • Strikt: Gibt an, dass alle Aufrufe für den Schein eine Ausnahme auslösen, wenn sie nicht explizit festgelegt werden.
  • CallOriginal: Gibt an, dass standardmäßig alle Aufrufe an Mock das entsprechende Originalelement aufrufen, sofern nicht bestimmte Erwartungen gesetzt sind.
+0

Ich habe den Mock modifiziert, um ein strenges Verhalten zu haben und der Service wird immer noch aufgerufen. 'mockDao = Mock.Create (Behavior.Strict);' – mam8cc

+1

@ mam8cc: Versuchen Sie, ein ['[TestInitialize()]'] (http://msdn.microsoft.com/en-us/library/microsoft .visualstudio.testtools.unittesting.testinitializeattribute.aspx) Methode und verschiebe die Instanziierung von 'mockClient' und' mockDao' in sie anstelle des Konstruktors 'FormControllerTest()'. Macht das einen Unterschied? –

+0

Nein, tut es leider nicht. Gleiches Ergebnis. Als ein paar zusätzliche Informationen habe ich durch Debuggen überprüft, dass das SurveyDao auf ein Mock gesetzt wird, nur um sicher zu gehen. – mam8cc