Znalazłem usługi testowania internetowych, konkretnie klienta WCF i serwer, przydatne na górze regularnych testów jednostkowych w następujących scenariuszach:
- testowania odbiorczego, w którym chcesz czarnej skrzynki przetestować całą swoją usługę i kłuć rzeczy w kończynach.
- Testowanie określonego przewodu WCF, rozszerzenie, zachowanie itp.
- Testowanie poprawności konfiguracji interfejsu i elementów danych.
W większości przypadków próbuję użyć bardzo prostej konfiguracji z podstawowym protokołem http i połączyć wszystko w kodzie. O ile nie jestem integratorem ani testem akceptacyjnym, nie testuję klienta na serwerze, zamiast tego kpię z jednego z nich, aby móc przetestować drugi w izolacji. Poniżej przedstawiono przykłady, jak przetestować klientów i usług WCF:
public static ServiceHost CreateServiceHost<TServiceToHost>(TServiceToHost serviceToHost, Uri baseAddress, string endpointAddress)
{
var serviceHost = new ServiceHost(serviceToHost, new[] { baseAddress });
serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
serviceHost.Description.Behaviors.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;
serviceHost.AddServiceEndpoint(typeof(TServiceToHost), new BasicHttpBinding(), endpointAddress);
return serviceHost;
}
//Testing Service
[TestFixture]
class TestService
{
private ServiceHost myServiceUnderTestHost;
private ChannelFactory<IMyServiceUnderTest> myServiceUnderTestProxyFactory;
[SetUp]
public void SetUp()
{
IMyServiceUnderTest myServiceUnderTest = new MyServiceUnderTest();
myServiceUnderTestHost = CreateServiceHost<IMyServiceUnderTest>(myServiceUnderTest, new Uri("http://localhost:12345"), "ServiceEndPoint");
myServiceUnderTestHost.Open();
myServiceUnderTestProxyFactory = new ChannelFactory<IMyServiceUnderTest>(new BasicHttpBinding(), new EndpointAddress("http://localhost:12345/ServiceEndPoint"));
}
[TearDown]
public void TearDown()
{
myServiceUnderTestProxyFactory.Close();
myServiceUnderTestHost.Close();
}
[Test]
public void SomeTest()
{
IMyServiceUnderTest serviceProxy = myServiceUnderTestProxyFactory.CreateChannel();
serviceProxy.SomeMethodCall();
}
}
//Testing Client
[TestFixture]
class TestService
{
private ServiceHost myMockedServiceUnderTestHost;
private IMyServiceUnderTest myMockedServiceUnderTest;
[SetUp]
public void SetUp()
{
myMockedServiceUnderTest = Substitute.For<IMyServiceUnderTest>(); //Using nsubstitute
myServiceUnderTestHost = CreateServiceHost<IMyServiceUnderTest>(myMockedServiceUnderTest, new Uri("http://localhost:12345"), "ServiceEndPoint");
myServiceUnderTestHost.Open();
}
[TearDown]
public void TearDown()
{
myServiceUnderTestHost.Close();
}
[Test]
public void SomeTest()
{
//Create client and invoke methods that will call service
//Will need some way of configuring the binding
var client = new myClientUnderTest();
client.DoWork();
//Assert that method was called on the server
myMockedServiceUnderTest.Recieved().SomeMethodCall();
}
}
UWAGA
ja zapomniałem wspomnieć, że jeśli chcesz, aby drwić usług WCF za pomocą czegoś, który używa zamków dynamicznego proxy następnie będzie musisz uniemożliwić skopiowanie ServiceContractAttribute
do wersji próbnej. Mam na to blog post, ale w zasadzie rejestrujesz atrybut jako jeden, aby zapobiec replikacji przed utworzeniem makiety.
Castle.DynamicProxy.Generators.AttributesToAvoidReplicating
.Add<ServiceContractAttribute>();