2010-12-14 6 views
0

Benötigen Sie Hilfe beim Zusammenstellen. (Angenommen, ich habe keinen TypeMock)Wie würden Sie diesen Code vereinigen?

Möchten Sie den Code ändern, um Mocks zu injizieren, um EndpointAddress, DiscoveryEndpoint, DiscoveryClient zu ersetzen?

Welche Art von Tests würden Sie schreiben? Ich kann mir

GetService_ServiceExist_ResultShouldBeAnInstance

GetService_ServiceIsNotExist_ResultShouldNull

static public T GetService<T>(Binding binding, string address) 
    { 
     Contract.Requires(binding != null); 
     Contract.Requires(!string.IsNullOrWhiteSpace(address)); 

     var endpointAddress= new EndpointAddress(address); 
     var discoveryEndpoint = new DiscoveryEndpoint(binding, endpointAddress); 

     var discoveryClient = new DiscoveryClient(discoveryEndpoint); 

     try 
     { 
      // Find ICalculatorService endpoints    
      FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(T))); 

      Contract.Assume(findResponse != null); 
      Contract.Assume(findResponse.Endpoints != null); 


      // Check to see if endpoints were found, if so then invoke the service.);); 
      if (findResponse.Endpoints.Count > 0) 
      { 
       Contract.Assume(findResponse.Endpoints[0] != null); 

       return ChannelFactory<T>.CreateChannel(new BasicHttpBinding(), 
                    findResponse.Endpoints[0].Address); 
      } 
     } 
     catch (TargetInvocationException ex) 
     { 
      Console.WriteLine("This client was unable to connect to and query the proxy. Ensure that the proxy is up and running: " + ex); 
     } 
     return default(T); 
    } 

alle Ihre Hilfe schätzen. Danke!

Ariel

Antwort

1

Sie haben eine Abhängigkeit von EndpointAddress, DiscoveryEndpoint und DiscoveryClient in Ihrer Methode.

Zunächst einmal würde ich diesen Code in etwas wie eine Fabrik setzen. Ich würde auch die oben genannten Abhängigkeiten in Fabriken wenn notwendig setzen und dann diese Fabriken in die Klasse unter Verwendung IOC einspritzen.

Dann kann ich gefälschte Objekte (oder Mocks) in das System für Komponententests setzen und ich muss mich nicht auf einen konkreten discoveryclient verlassen (zum Beispiel). Aber wenn das kein Problem ist, würde ich es trotzdem herstellen.

Sie suchen auch nach einem Endpunkt und erstellen einen Kanal oder eine Ausnahme. Nun, wenn Sie bei den oben genannten bleiben, dann müssen Sie Standard (T) zurückgeben.

Wahl hier ist, entweder den Code dort zu halten und dann die Ausnahme zu werfen, anstatt Null zurückgeben, null zurückgeben und dafür testen, diese Methode nur eine Sache machen, die versucht, einen Kanal basierend auf einem konfigurierten zu erstellen DiscoveryClient.

Wenn ich es tun würde, würde ich alle diese Abhängigkeiten entfernen, es zu einer Fabrik machen (und die anderen aus Fabriken wie nötig), dann einen konfigurierten DiscoveryClient übergeben und entweder Null zurückgeben oder eine NullChannel-Instanz zurückgeben.

Dann kann ich eine Assert auf die Instanz in meinem Test zurückgegeben und die Erstellungsmethode hat nur eine Verantwortung.

HTH

+0

Glauben Sie nicht, dass IoC die hier Abhängigkeiten der API verschmutzen würde? – ArielBH

+0

Ehrlich nein. Der Code, den Sie haben, beruht auf anderen Komponenten in Ihrem System. Warum also nicht explizit dieses Vertrauen ausdrücken, indem man diese über den Konstruktor weitergibt? Wenn nichts anderes, können Sie diese Elemente manuell erstellen, aber selbst dann, wenn Sie es sind, würde ich die Verwendung von Fabriken in Betracht ziehen, um es für Sie zu tun. Bis zu Ihnen wirklich - Sie müssen nicht IOC verwenden, aber wenn Sie mit etwas mit irgendeiner Komplexität beschäftigen, dann würde ich es verwenden. – Simon

+0

Simon, Danke. Refactoring jetzt. Ich werde von einer statischen API zurücktreten ... (Ich benutze einen IoC Container ...) – ArielBH