RhinoMock help: Mocking WCF service - wcf

I'm trying to use RhinoMock for mocking out a wcf service.
Say I have the following service:
[OperationContract]
List<User> SearchUsers(UserSearchFilter filter);
Adding this service with Visual Studio will generate a proxy, and that proxy has a Interface like:
public interface ResourceService {
System.IAsyncResult BeginSearchUsers(UserSearchFilter filter, System.AsyncCallback callback, object asyncState);
ObservableCollection<User> EndSearchUsers(System.IAsyncResult result);
}
Then I create a ViewModel that uses this service, like this:
private ResourceService service;
public ViewModelBase(ResourceService serv)
{
service = serv;
var filter = new UserSearchFilter();
service.BeginSearchUsers(filter, a =>
{
this.Users = service.EndSearchUsers(a);
}, null);
}
Then comes the question. How do I mock this service using RhinoMock?
[TestMethod]
public void UserGetsPopulatedOnCreationOfViewModel()
{
// Is stub the right thing to use?
ResourceService serv = MockRepository.GenerateStub<ResourceService>();
// Do some setup... Don't know how?
var vm = new ViewModel(serv);
Assert.IsTrue(vm.Users.Count > 0);
}
I be really happy if someone could help me with the correct usage of RhinoMock
(Note: I'm using Silverlight, but I don't think that would change the way RhinoMock is used)
Thanks a lot!

I wrote a 4-part article all about testing apps that use WCF services.
Part 2 talks about mocking out the service using RhinoMocks
Part 3 talks about mocking out an asynchronous service using Moq
Note that part 3 can be translated over to RhinoMocks very easily. I was just trying to show different mocking frameworks, and that the technique did not rely on the mocking framework.
Hope it helps!
EDIT
So, in Rhino Mocks, you do this in the setup:
mockService.YourEvent += null;
IEventRaiser loadRaiser = LastCall.IgnoreArguments().GetEventRaiser();
Then in the playback, you do this:
loadRaiser.Raise(mockService, CreateEventArgs());
You can find more info on mocking events in Rhino in Phil Haack's blog post.

I would create interface that service would implement (IResourceService).
Then on Silverlight side create custom implementation of IResourceService that calls WCF service itself.
RihnoMock would create the stub for IResourceService interface and not for WCF service.
It's very easy to do using Prism 2, you can read more here:
http://mokosh.co.uk/post/2009/04/19/prism-2-wpf-and-silverlight-services/

Related

WCF Task based asynchronous callback

I have created WCF service in VS2015:
[ServiceContract(CallbackContract = typeof(IMyCallback))]
public interface IMyService { }
IMyCallback looks like:
[ServiceContract]
public interface IMyCallback {
[OperationContract]
Task<string> OnServerEvent(UserAppEventData evData);
I've built the server, run it, then added service reference (by right click on solution explorer).
The client object is defined as
[CallbackBehaviorAttribute(
ConcurrencyMode = ConcurrencyMode.Reentrant,
IncludeExceptionDetailInFaults = true,
UseSynchronizationContext = true,
ValidateMustUnderstand = true
)]
public class QMyClient : IMyCallback { }
Automatically generated interface implementation made method in sync manner:
public string OnServerEvent(UserAppEventData evData) { }
This code does't work (and isn't asynchronous) and hangs client at OnServerEvent.
When I changed code manuallly to
public async Task<string> OnServerEvent(UserAppEventData evData)
and have done the same in auto generated "service references\...\Reference.cs, all works fine. But I don't want to change Referenece.cs every time I'm updating Service Reference.
Is there any method to force "Update Service Reference" make TBA OperationContractAttribute on callback?
At ordinary WCF service direction everything works OK, VS generates task based operations.
By default the service reference you've added to solution doesn't have asynchronous operations, but you can enable them and decide which option you use for your async methods - task-based or old-fashion asynchronous. This option is available in Advanced settings for service reference.
If you're using a svcutil tool, it will create the task-based methods by default, however, you can change that behavior by some flags like /async or /syncOnly.
What #VMAtm suggested will work out just fine.
I think, you could also use ChannelFactory for this scenario. It is very flexible and you can then await on the service operations from client side. Additional benefit, you don't need to modify client when there are these kind of changes on service side.
Something like:
var channelFactory = new ChannelFactory<IService>(
"WSHttpBinding_IService" // endpoint name
);
IService channel = channelFactory.CreateChannel();
string result = await channel.OnServerEvent();
Console.WriteLine(result);
Please note that for this scenario, you will have to import common interface library to client side as dll because then it will need to know about contracts and data contracts.

Is ChannelFactory with async methods in .NET 4.5 supported?

I'm in the process of converting our WCF services to use async programming. As expected the interface looks like this:
public interface IFoo
{
Task<string> DoSomething(string request);
}
On the client side I'm not creating a service reference from Visual Studio. Since I own both client and server I just share the interface with the client, then I create (and cache) a ChannelFactory. To invoke the method asynchronously I use the expected syntax:
IFoo clientChannel = channelFactory.CreateChannel();
bool result = await clientChannel.DoSomething("Hello World");
My question is: Is the IClientChannel generated by the ChannelFactory really using the async features underneath? I mean, can I be sure there's no thread blocked waiting for the server response?
Looking at the ClientBase code, async calls all boil down to:
http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Channels/ServiceChannel.cs,0353de22100bb396
There doesn't seem to be any reason to think the thread would block waiting for a network response.

Recommended patterns for unit testing web services

We are about to begin architecting a service oriented framework (SOA) which will certainly involve a high number of of granular web services (REST in WCF). We've been quite disciplined in unit testing our client and server-side code base, however we don't have much of any experience in unit testing web services. We're really looking for guidance as to where the tests should be written and recommendations on what approach to use when unit testing our services.
Should we write tests that make http requests and assert that the responses are what they should be? Should we focus on just testing the internal logic of the service methods themselves and not worry about testing the actual requests? Or should we do both? Are there any other recommendations for what we should be testing?
We're really looking for some explanation and guidance and would truly appreciate any advice we can get.
I have found testing web services, specifically WCF client and server, useful on top of regular unit testing in the following scenarios:
Acceptance testing where you want to black box test your whole service and poke things in at the extremities.
Testing a specific WCF wire up, extension, behavior, etc.
Testing that your interface and your data members are setup correctly.
Most of the time I try to use a very basic setup with basic http and wire everything up in the code. Unless I am Integration or Acceptance testing I don't test the client against the server, instead I mock one of them so that I can test the other in isolation. Below are examples of how I test WCF clients and services:
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();
}
}
NOTE
I had forgot to mention that if you want to mock a WCF service using anything that uses castles dynamic proxy then you will need to prevent the ServiceContractAttribute from being copied to the mock. I have a blog post on this but basically you register the attribute as one to prevent from replication before you create the mock.
Castle.DynamicProxy.Generators.AttributesToAvoidReplicating
.Add<ServiceContractAttribute>();
Well basically I think that you need to have a two part test strategy.
The first part would be true unit tests, which would involve testing the classes completely independent of any web request ... as the main definition of a unit test is one that runs without the need of extra environments or setups other than the ones in the test itself.
So you would create unit test projects, in which you would instantiate the code classes of your WCF services to make sure the logic is correct, in much the same way that you test the rest of your classes.
The second part would be a set of integration tests, which would test your application in an end-to-end fashion. Of course, here you need the whole enchilada, web server, database, and so forth.
This way you know that your logic is accurate and also that your application works.

Issue with mocking WCF service

I have some problems with mocking WCF services:
1) I declare a class with empty methods which only implements my service interface:
public class MyFakeService : IMyService {
...
public virtual MyResult GetResult(MyResponse response){
throw new NotImplementedException();
};
}
2) I have the MyResponse class:
public class MyResponse {
public long myField;
}
3) I create a mock of the service class and a service host to host this fake service:
myFakeService = mocks.StrictMock<MyFakeService>();
ServiceHost host = new ServiceHost(myFakeService);
(here I have ommited the endpoint configuration etc.)
4) And now I try to test my client. The client.GetSomethingFromService() method exactly calls the GetResult(MyResponse) method of the service.
With.Mocks(mocks)
.Expecting(() => Expect
.Call(myFakeService.GetResult(null))
.IgnoreArguments()
.Constraints(PublicField.Value("myField", 777))
.Return(new MyResult()))
.Verify(() => myClient.GetSomethingFromService());
The issue is that if something wrong in the service, I can only see something like this:
System.ServiceModel.CommunicationObjectFaultedException:
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used
for communication because it is in the Faulted state.
How do I know what exactly wrong? Maybe arguments constraints verification failed or something else...?
Thanks.
Firstly, avoid using strict mocks. They're a bad practice because they make your tests too brittle.
Secondly if you're testing a WCF service you don't need to spin up a ServiceHost since you'll then be doing an integration test. You're just wanting to test the logic of your service, not the WCF infrastructure.
For a run through of how to use RhinoMocks and WCF services have a look at my blog post on unit testing WCF services

RESTful framework alternatives to WCF

Looking for alternatives to the WCF REST start kit, ideally OSS frameworks.
Anyone got a list?
Cheers
Ollie
OpenRASTA is the most mature
ASP.NET MVC is a good alternative when it comes to generating REST XML and JSON feeds.
To build a rest architecture in .net you can use GenericHandlers. You can create a GenericHandler that will receive a HTTP message (POST, GET or..) and return a message of the content-type you specify.
For example I create a generic handler on the url:
http://site/getpeople.ashx?gender=female
And call it with the parmeter gender=female, as above the handler will return the following
<people>
<person>...</person>
...
<people>
And the content type would be text/xml.
This is the simplest way to implement REST web services in .NET
I also provide ServiceStack, a modern, code-first, DTO-driven, WCF replacement web services framework encouraging code and remote best-practices for creating DRY, high-perfomance, scalable REST web services.
There's no XML config, or code-gen and your one clean C# web service is enabled on all JSON, XML, SOAP, JSV, CSV, HTML endpoints out-of-the-box, automatically. It includes generic sync/async service clients providing a fast, typed, client/server communication gateway end-to-end.
It also includes generic sync/async service clients providing a fast, typed, client/server communication gateway end-to-end.
This is the complete example of all the code needed to create a simple web service, that is automatically without any config, registered and made available on all the web data formats on pre-defined and custom REST-ful routes:
public class Hello {
public string Name { get; set; }
}
public class HelloResponse {
public string Result { get; set; }
}
public class HelloService : IService<Hello> {
public object Execute(Hello request) {
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
Above service can be called (without any build-steps/code-gen) in C# with the line below:
var response = client.Send<HelloResponse>(new Hello { Name = "World!" });
Console.WriteLine(response.Result); // => Hello, World
And in jQuery with:
$.getJSON('hello/World!', function(r){
alert(r.Result);
});