Wie zum Hohn WCF-client über Moq?
In meinem Projekt verwende ich: SL5+ MVVM+ PRISMA + WCF + Rx + Moq + Silverlight Unit Test Framework.
Ich bin neu in unit-Tests und habe vor kurzem angefangen, in DI, Muster (MVVM) - etc. Daher ist der folgende code ist eine Menge Spielraum für Verbesserung (fiel bitte frei, lehnen den ganzen Ansatz, den ich nehme, wenn Sie so denken).
Zugriff auf meine WCF-Dienste, die ich erstellt habe, eine factory-Klasse wie folgt (wieder, es kann fehlerhaft sein, aber bitte haben Sie einen Blick):
namespace SomeSolution
{
public class ServiceClientFactory:IServiceClientFactory
{
public CourseServiceClient GetCourseServiceClient()
{
var client = new CourseServiceClient();
client.ChannelFactory.Faulted += (s, e) => client.Abort();
if(client.State== CommunicationState.Closed){client.InnerChannel.Open();}
return client;
}
public ConfigServiceClient GetConfigServiceClient()
{
var client = new ConfigServiceClient();
client.ChannelFactory.Faulted += (s, e) => client.Abort();
if (client.State == CommunicationState.Closed) { client.InnerChannel.Open(); }
return client;
}
public ContactServiceClient GetContactServiceClient()
{
var client = new ContactServiceClient();
client.ChannelFactory.Faulted += (s, e) => client.Abort();
if (client.State == CommunicationState.Closed) { client.InnerChannel.Open(); }
return client;
}
}
}
Es implementiert eine einfache Schnittstelle wie unten:
public interface IServiceClientFactory
{
CourseServiceClient GetCourseServiceClient();
ConfigServiceClient GetConfigServiceClient();
ContactServiceClient GetContactServiceClient();
}
In meinem VMs mache ich DI von der obigen Klasse und mit Rx call WCF wie folgt:
var client = _serviceClientFactory.GetContactServiceClient();
try
{
IObservable<IEvent<GetContactByIdCompletedEventArgs>> observable =
Observable.FromEvent<GetContactByIdCompletedEventArgs>(client, "GetContactByIdCompleted").Take(1);
observable.Subscribe(
e =>
{
if (e.EventArgs.Error == null)
{
//some code here that needs to be unit-tested
}
},
ex =>
{
_errorLogger.ProcessError(GetType().Name, MethodBase.GetCurrentMethod().Name, ErrorSource.Observable, "", -1, ex);
}
);
client.GetContactByIdAsync(contactid, UserInformation.SecurityToken);
}
catch (Exception ex)
{
_errorLogger.ProcessError(GetType().Name, MethodBase.GetCurrentMethod().Name, ErrorSource.Code, "", -1, ex);
}
Nun will ich bauen, unit-tests (ja, es ist nicht TDD). Aber ich verstehe nicht, wo zu beginnen. Mit Moq kann ich nicht verspotten die BlahServiceClient. Auch keine svcutil erzeugt-Schnittstelle helfen können, weil async-Methoden sind nicht Teil der automatisch generierten IBlahService-Schnittstelle. Ich mag lieber verlängern (durch partielle Klassen usw.) die automatisch generierten Klassen, aber ich würde es hassen, entscheiden Sie sich für manuell erstellen Sie den code, der svcutil erzeugen kann (ehrlich gesagt, in Anbetracht der Zeit und budget).
Kann mir bitte jemand helfen? Alle Zeiger in die richtige Richtung würde mir sehr helfen.
Das ist sehr wahr Michal. Sollte ich umgestalten, meinen code zu isolieren, die einer anderen Logik von WCF-Aufruf. Vielen Dank.
Es gibt nicht viel umgestalten, hier. Legen Sie einfach Ihren "code" in seiner eigenen Methode und testen Sie diese Methode. Keine Notwendigkeit zum testen der WCF-Sachen dann.
in meinem Fall, habe ich gerade getan, die Schaffung eines service. Wir wollen, unit-tests, um sicherzustellen, telefonieren via wsdl arbeitet immer so, wir brauchen eine süße von tests. So versuche ich unit-test-meine service-Methoden...als ob ich ein client nutzt den Webdienst. Also meine Absicht ist, die zum aufrufen von Methoden angegeben, die in der WSDL als eine hypothetische Kunde/Verbraucher von my web service. Jetzt auf der anderen Seite könnte ich auch wollen, erstellen von unit-tests direkt in mein SErvice-Projekt selbst zu testen, die Methoden? Nicht sicher über das, was unit-Tests.
was ist der client.ChannelFactory zu tun?
InformationsquelleAutor Dharmesh | 2012-12-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Spott, wenn Sie Ihre service-client, den Sie eigentlich mocking eine der Schnittstellen, die Sie implementiert. Also in deinem Fall kann es sein
IContactService
.Der generierte code implementiert die beiden
System.ServiceModel.ClientBase<IContactService>
undIContactService
. Ihre Abhängigkeit von den Anbieter (in Ihrem Fall ein factory) zurückContactServiceClient
- ändern Sie dies, umIContactService
für den Anfang. Dies wird helfen, Ihre DI jetzt und in der Zukunft.Ok, du bist schon über eine abstrakte Fabrik-und nun kehren Sie Ihre service-Schnittstelle
IContactService
. Sie sind über Schnittstellen nur jetzt so der Spott ist ziemlich trivial.Zunächst einige Annahmen über den code, den Sie versuchen zu trainieren. Das code-snippet bereitgestellt Nachrichten, die sowohl der abstrakten Fabrik und der service-client. Vorausgesetzt, dass die //etwas code hier, muss sein Gerät getestet Abschnitt ist nicht für die Interaktion mit anderen Abhängigkeiten dann bist du auf der Suche nach mock in dem sowohl die Fabrik und den service-client, so dass Sie test isoliert, wird nur die Methode-Körper-code.
Habe ich eine Einstellung für den sake des Beispiels. Ihre Schnittstellen:
Dann ist dein test Aussehen würde, zusammenfassend so:
EDIT: lustig das Async-Methoden
Den async-Methoden generiert werden, die nicht Teil der service-Methoden und erstellt von der WCF als Teil der Client-Klasse. Zu verspotten diejenigen, die als eine Schnittstelle Folgendes tun:
Auszug der Schnittstelle des
ContactServiceClient
Klasse. In VS ist es einfach ein rechts-Klick (auf den Namen der Klasse), refactor, extract interface. Und wählen Sie nur die anwendbaren Methoden.Den
ContactServiceClient
Klasse ist teilweise so erstellen Sie eine neue Klasse-Datei und neu zu definieren, ContactServiceClient Klasse zum implementieren der neuenIContactServiceClient
Schnittstelle, die Sie gerade extrahiert.Wie so und jetzt die client-Klasse implementiert AUCH die neue Oberfläche mit den ausgewählten async-Methoden. Beim aktualisieren Sie Ihren service-Schnittstelle und der service-Klasse neu erzeugt - Sie müssen nicht re-extrahieren Sie die Schnittstelle, die Sie erstellt haben eine separate partial-Klasse mit der interface-Referenz.
Erstellen Sie eine neue Fabrik, um die Rückkehr der neuen Schnittstelle
Ändern Sie die test arbeiten mit dieser Schnittstelle.
Sie müssen nicht von hand code die asynchrone Schnittstelle, um das gleiche Ergebnis zu erzielen. Ich werde es auf meine Antwort
Nochmals vielen Dank Quinton.
Ihre Lösung für das Async-problem ist problematisch, da die gesamte Idee der code-Generierung ist, dass es "einfach funktioniert". Wenn die OP-switches zu verwenden, die manuell extrahiert ICourseServiceClient, dann das nächste mal die IDL-Veränderungen, wird er haben, um re-extrahieren Sie die Schnittstelle, um die Veränderungen in seinem code. Machbar, aber nervig und fehleranfällig.
Hilfreiche Antwort. Doch der "Kontakt" und "Natürlich" sind die Klassen Durcheinander in deinem code, in Bezug auf die OP ' s Frage. Würden Sie dagegen, mit nur einer von denen?
InformationsquelleAutor Quinton Bernhardt