Ich bin mit FakeItEasy, die nicht für Mocking von OperationContext erlaubt, weil es eine versiegelte Klasse ist. Fügen Sie Abhängigkeit Injektion in den Mix, und Sie haben sich eine straight-up-Albtraum. Ich habe eine Woche damit verbracht, dieses Zeug herauszufinden, und hier ist, was ich schließlich herausgefunden habe Sie werden ein paar von ServiceHost
und dann werden sie miteinander kommunizieren und Ihren gesamten Code dazwischen ausführen.
1 Erstellen Sie eine Klasse, die erbt von ClientBase<IMyWcfService>
:
public class MyWcfServiceClient : ClientBase<IMyWcfService>, IMyWcfService
{
public MyWcfServiceClient(string address)
: base(new WebHttpBinding(), new EndpointAddress(address))
{
this.Endpoint.EndpointBehaviors.Add(new WebHttpBehavior());
}
public void CallMyStuff()
{
using (new OperationContextScope(this.InnerChannel))
{
base.Channel.CallMyStuff();
}
}
}
2 Erstellen Sie einen "aufrufenden Dienst", der diese Methode aufrufen wird. Erstellen Sie zunächst eine Schnittstelle:
[ServiceContract]
public interface IMyWcfCallingService
{
[OperationContract]
void CallCallMyStuff();
}
Erstellen Sie dann den "aufrufenden Dienst", der diese Schnittstelle implementiert:
public class MyWcfCallingService : IMyWcfCallingService
{
static MyWcfServiceClient _client = new MyWcfServiceClient("http://localhost:8008");
// ^^^ This "http://localhost:8008" is the address where
// your actual service is going to "live" in your unit test
public void CallCallMyStuff()
{
_client.CallMyStuff();
}
}
3 Instanziieren Sie Ihren eigentlichen Dienst im Einheitstest:
var myService = new MyWcfService(_someMockedDependency, _someOtherMockedDependency);
4 Erstellen Sie die beiden ServiceHost
die miteinander sprechen und Ihren Dienst anrufen werden:
var restHost = new WebServiceHost(myService, new Uri("http://localhost:8008"));
// ^^^ Make sure the URL here matches the URL you used in Step #2
var behavior = restHost.Description.Behaviors.Find<ServiceBehaviorAttribute>();
behavior.InstanceContextMode = InstanceContextMode.Single;
// ^^^ If you're using dependency injection with mocked dependencies
// to create your myService object, this is muy importante
restHost.Open();
var clientHost = new ServiceHost(typeof(MyWcfCallingService), new Uri("http://localhost:80"));
// ^^^ use some other address here, different from the one you used for the service itself
clientHost.AddServiceEndpoint(typeof(IMyWcfCallingService), new BasicHttpBinding(), string.Empty);
clientHost.Open();
var factory = new ChannelFactory<IMyWcfCallingService>(new BasicHttpBinding(), new EndpointAddress("http://localhost:80"));
// ^^^ this should match the url for the clienthost
var proxy = factory.CreateChannel();
proxy.CallCallMyStuff();
Verdammt sei die WCF! Ich habe WebApi nie so sehr geschätzt, wie als ich anfing, mich durch veralteten WCF-Code zu wühlen.