How to unit test a WCF Client built with WCF Rest Starter Kit - wcf

I created some POX services using the REST Starter kit.
At first, it was a little complicated to create the unit tests for the service layer, but in the end, it was well designed and I succeed in mocking the context and set expectations.
But, I'm starting in with the client side now, and I'm having some problems figuring out how to mock things. It's not so straight forward.
So, I have this sample method that post via HTTP some data using a datacontract and XML as transport.
public class ServiceClient: IService
{
private const string uri_template = "http://{0}:{1}/SomeService.svc/";
private readonly HttpClient http = new HttpClient();
public ServiceClient(string host, int port)
{
http.BaseAddress = new Uri(string.Format(uri_template , host, port));
}
public void Create(MyDataContract my_data_contract)
{
var content = HttpContentExtensions
.CreateDataContract(
my_data_contract,
Encoding.Default,
"text/xml",
null);
var response = http.Post("Create", content);
if (response.StatusCode != HttpStatusCode.Created) {
throw new Exception("something is not right");
}
}
}
This method is working and indeed posting the data and serializing correctly.
What I want to do, is to unit test it.
My questions are:
How do I make stubs/mocks for HttpContextExtensions knowing that it does not implement any interface?
And for HttpClient? this is worst since it is full of extension methods defined elsewhere (Post and the like methods are extensions).
In 2. I guess I can stick to 'Send' and it's overloads, but then is the same problem as in 1
What I was thinking to do, is to extract interfaces for HttpContextExtensions and HttpClient, make a children for each one and implement the interfaces delegating to the parent, and then using the interfaces in my code.
But that's a lot of work IMHO.
I'm using RhinoMocks as my mocking framework so I can't mock/stub concrete classes, and I would like to stick to it, because I really think that mocking concrete classes is not very elegant.
So, is there a cleaner/faster/smarter way to unit test code like the above?
PD: This is for WCF Starter Kit preview 2

If you really want to mock that code, an approach that could work for this scenario is to receive an HttpClient instance in the ServiceClient class. The HttpClient class contains a processing pipeline that you can customize with custom handlers. For your tests, you can basically inject a handler in that httpclient instance to return a mocked response to the test before the real service is called in the last handler (Transport Stage). Take a look at this post to get an idea about how this can be implemented,
http://weblogs.asp.net/cibrax/archive/2009/03/18/negotiating-a-saml-token-for-rest-clients-with-httpclient.aspx
Regards,
Pablo.

I wrote most of the HttpClient code. Pablo's suggestion is what I did in the unit tests -- see FixedTransport.cs in the source zip.

Related

NServiceBus Removing IBus - Utilising IPipelineContext and IMessageSession

I am in the process of migrating NServiceBus up to v6 and am at a roadblock in the process of removing reference to IBus.
We build upon a common library for many of our applications (Website, Micro Services etc) and this library has the concept of IEventPublisher which is essentially a Send and Publish interface. This library has no knowledge of NSB.
We can then supply the implementation of this IEventPublisher using DI from the application, this allows the library's message passing to be replaced with another technology very easily.
So what we end up with is an implementation similar to
public class NsbEventPublisher : IEventPublisher
{
IEndpointInstance _instance;
public NsbEventPublisher(IEndpointInstance endpoint)
{
instance = endpoint;
}
public void Send(object message)
{
instance.Send(message, sendOptions);
}
public void Publish(object message)
{
instance.Publish(message, sendOptions);
}
}
This is a simplification of what actually happens but illustrates my problem.
Now when the DI container is asked for an IEventPublisher it knows to return a NsbEventPublisher and it knows to resolve the IEndpointInstance as we bind this in the bootstrapper for the website to the container as a singleton.
All is fine and my site runs perfect.
I am now migrating the micro-services (running in NSB.Host) and the DI container is refusing to resolve IEndpointInstance when resolving the dependencies within a message handler. Reading the docs this is intentional and I should be using IMessageHandlerContext when in a message handler.
https://docs.particular.net/nservicebus/upgrades/5to6/moving-away-from-ibus
The docs even elude to the issue I have in the bottom example around the class MyContextAccessingDependency. The suggestion is to pass the message context through the method which puts a hard dependency on the code running in the context of a message handler.
What I would like to do is have access to a sender/publisher and the DI container can give me the correct implementation. The code does not need any concept of the caller and if it was called from a message handler or from a self hosted application that just wants to publish.
I see that there is two interfaces for communicating with the "Bus" IPipelineContext and IMessageSession which IMessageHandlerContext and IEndpointInstance interfaces extend respectively.
What I am wondering is there some unification of the two interfaces that gets bound by NSB into the container so I can accept an interface that sends/publishes messages. In a handler it is an IMessageHandlerContext and on my self hosted application the IEndPointInstance.
For now I am looking to change my implementation of IEventPublisher depending on application hosting. I was just hoping there might be some discussion about how this approach is modeled without a reliable interface to send/publish irrespective of what initiated the execution of the code path.
A few things to note before I get to the code:
The abstraction over abstraction promise, never works. I have never seen the argument of "I'm going to abstract ESB/Messaging/Database/ORM so that I can swap it in future" work. ever.
When you abstract message sending functionality like that, you'll lose some of the features the library provides. In this case, you can't perform 'Conversations' or use 'Sagas' which would hinder your overall experience, e.g. when using monitoring tools and watching diagrams in ServiceInsight, you won't see the whole picture but only nugets of messages passing through the system.
Now in order to make that work, you need to register IEndpointInstance in your container when your endpoint starts up. Then that interface can be used in your dependency injection e.g. in NsbEventPublisher to send the messages.
Something like this (depending which IoC container you're using, here I assume Autofac):
static async Task AsyncMain()
{
IEndpointInstance endpoint = null;
var builder = new ContainerBuilder();
builder.Register(x => endpoint)
.As<IEndpointInstance>()
.SingleInstance();
//Endpoint configuration goes here...
endpoint = await Endpoint.Start(busConfiguration)
.ConfigureAwait(false);
}
The issues with using IEndpointInstance / IMessageSession are mentioned here.

Moq SignalR Client events

I have a service that uses the SignalR .Net Client to communicate with the server, and I want to add some test to check how the client will react to connection problems (Slow-Internet, Intermittent Connection, No connection at all), the problem is that I don´t know how to mock this so that I can create the tests.
I´m new at mocking so I´m having a hard time with this.
You need to design your code so that you only have dependecy to the IHubProxy interface
You can look at my .NET client library to see how it can be solved
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/tree/master/SignalR.EventAggregatorProxy.Client.DotNet
In my case some of the code needed the actual concrete HubProxy so what I did was to create a factory that returns a IHubProxy, in that way I could do the stuff that had depedency to the concrete type fro that factory and all other code relied on dependecy to IHubProxy that way I could mock the concrete HubProxyFactory and the HubProxy code
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/blob/master/SignalR.EventAggregatorProxy.Client.DotNet/Bootstrap/Factories/HubProxyFactory.cs
After the code is adjusted its just a matter of some Mock magic, in my case
WhenCalling<IHubProxyFactory>(x => x.Create(Arg<string>.Is.Anything, Arg<Action<IHubConnection>>.Is.Anything, Arg<Action<IHubProxy>>.Is.Anything, Arg<Action>.Is.Anything, Arg<Action<Exception>>.Is.Anything, Arg<Action>.Is.Anything))
.Callback<string, Action<IHubConnection>, Action<IHubProxy>, Action, Action<Exception>, Action>((u, c, started, reconnected, f, connected) =>
{
started(proxy);
reconnectedCallback = reconnected;
return true;
})
.Return(proxy);

How to Consume MVC 4 WebApi Service

I am new to Web Api world and I see a lot of potential for in the new MVC 4 Web Api. I have generated a WCF Web Service but was planning to get to know Web-APIs and their web service capabilities. Now, is MVC 4 Web-Api Service more as front end? I wrote a sample Service by following some examples online in MVC 4 Web Api but how do I consume the Service in just a basic console app? I have figured out the only way to consume it is by using HttpClient are there other ways? I am used to ASP.NET Web Service and WCF Web Service as where you reference it as a service in your references and then you are able to see all of its objects, properties to make appropriate calls.
What happens if web-api is requesting a object "Task" for post method as an example how am I able to fill an object "Task" and post it back to the web-api? As in WCF I am able to see that "Task" object and its properties because of WSDL so I am able to fill them and send it back to the service how is that done in web-api service?
The webservice would be used internally is it worth it to have an web-api service?
Thank you so much for helping clearing some question of what I have about web-api services.
---Edit as per Comment---
This screenshot shows a possible structure which you can approach. Of course, you can take a design that best suit your application.
So ControllerLib is a separate Class Library project which is brought into the main project as a Service Reference (which is not shown in the screenshot but should be inside the References folder of the SecondMVCApplication project). The two controller file (HomeController.cs and LocationController.cs is a controller file that implemented the Controller class, which is the same thing as a Controller file when you create a new MVC4 application using the template)
So for your question regarding if there is a SVC file. NO. In MVC 4, there is no such thing as a SVC file whether the application is one project or a combination of multiple project (unless I am mistaken). Inside the SecondMVCApplication, there is a file called RouteConfig.cs which holds the routing URL and as long as you add the Service Reference and there controller function exists. The code will run. Also the sample screenshot I showed also includes a WebApiConfig.cs file. You can use that file to do API stuff for mobile if you need. So, the regular RouteConfig.cs handles website request and the WebApiConfig.cs handles API request.
Good to Note: If you are using a Model project as a separate project (which I know you will as it is a M-V-C project...DUH!!). Make sure you put your connection string inside the web.config main project (in this case, the SecondMVCApplication). I remember I was stuck in this problem for 3 days (8 hours each) trying to fix this problem. Hope you don't run into it.
---End Edit---
The following answer to your question is mostly based on my knowledge and may or may not be true to all users.
Is MVC 4 Web-Api Service more as front end?
This depends on how you look at it. Typically, a Web-API service is more suited for creating back-end service to provide a data payload to different platforms, like mobile, desktop apps and so on. However, a MVC4 Internet Application will have front-end aspects in them, namely the Views, which end-users sees.
How do I consume the Service in just a basic console app?
AFAIK, there is two way to do this. One if to consume the APIs as a Service Reference. Another is to use HTTP operation (which I will mention in your question regarding the HTTP client and reserve this answer using the Service Reference method).
This depends on how your application is done. Like I said, if it is a website, your MVC pattern will not need to do anything, but the Models, Views and Controllers all are designed to work together without using any service.
Although, as I mentioned in the comments to the questions, if it is a big application then you will need to break them into different projects that will make the app modular and nimble. So you will end up creating different Service Library. If you go down the Service Library road, then you just make use of the Add Reference option to bring in your API/Projects/Whatever-you-call-it into the project. (For this, I normally put all project inside a single solution and let Visual Studio manage the build order as I am lazy to write up a build script).
Similarly, the same logic could be applied when consuming your web service in a console app.
I have figured out the only way to consume it is by using HttpClient are there other ways?
One way to consume web APIs is using HTTP. Are you aware of how to write http request headers and handle http response. If so, this is the second way I mentioned. You call the web service through it's URL and then get the data and do whatever work. If your answer to use http in console app is NO, then look at this post: Create HTTP post request and receive response using C# console application
What happens if web-api is requesting a object "Task" for post method as an example how am I able to fill an object "Task" and post it back to the web-api?
I think I indirectly answered this in your previous answer (assuming you are going to take the HTTP road). If not, then comment and I'll see if I can find some resource for you.
The webservice would be used internally is it worth it to have an web-api service?
I sort of answered this in the comment to the question. Ask if you need clarification.
Hope all this helps.
you can create your own Client Service class that will serve for every request.
public class ClientService
{
#region async helper methods
private static string m_mediaTypeHeaderValue= "application/json";
static HttpClient client = new HttpClient();
static HttpClient createHttpClientInstance()
{
return client ?? new HttpClient();
}
// SELECT
internal static async Task<T> Get<T>(string endpoint)
{
client= createHttpClientInstance();
var response = await client.GetAsync(endpoint);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
// INSERT
static async Task<T> Post<T>(string endpoint, object data)
{
client = createHttpClientInstance();
var httpContent = new StringContent(JsonConvert.SerializeObject(data));
httpContent.Headers.ContentType = new MediaTypeHeaderValue(m_mediaTypeHeaderValue);
var response = await client.PostAsync(endpoint, httpContent);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
// UPDATE
static async Task<T> Put<T>(string endpoint, object data)
{
client = createHttpClientInstance();
var httpContent = new StringContent(JsonConvert.SerializeObject(data));
httpContent.Headers.ContentType = new MediaTypeHeaderValue(m_mediaTypeHeaderValue);
var response = await client.PutAsync(endpoint, httpContent);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
// DELETE
static async Task<T> Delete<T>(string endpoint)
{
client = createHttpClientInstance();
var response = await client.DeleteAsync(endpoint);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
#endregion
}

How do you inject wcf client dependencies in a ViewModel and keep it testable?

TL;DR:
What is a good and testable way to implement the dependency between the ViewModels and the WCF services in a MVVM client?
Please read the rest of the question for more details about the problems I encountered while trying to do this:
I am working on a silverlight client that connects to a wcf service, and I want to write unit tests for the client.
So I'm looking for a good solution for using the wcf clients in my ViewModels and testing that interaction. I have found two solutions until now:
Solution 1: This is actually how I have implemented it until now:
public class ViewModelExample
{
public ViewModelExample(IServiceClient client)
{
client.DoWorkCompleted += ..
client.DoWorkAsync();
}
}
//This is how the interface looks like
public interface IServiceClient
{
event EventHandler<AsyncCompletedEventArgs> DoWorkCompleted;
void DoWorkAsync();
}
//I was able to put the interface on the generated clients because they are partial classes, like this:
public partial class GeneratedServiceClient : IServiceClient
{
}
The good part: it's relatively easy to mock
The bad part: my service client lives as long as my ViewModel, and when I have concurrent requests I don't know which answer belongs to which request.
Solution 2: Inspired by this answer
WCF Service Client Lifetime.
public class ViewModelExample
{
public ViewModelExample(IServiceFactory factory)
{
var client = factory.CreateClient();
client.DoWorkCompleted += ...
client.DoWorkAsync();
}
}
The good part: each request is on a different client, so no more problems with matching requests with answers.
The bad part: it's more difficult to test. I would have to write mocks for both the factory and the wcf client every time. This is not something I would like to do, since I alreay have 200 tests... :(
So my question is, how do you guys do it? How do your ViewModels talk to the wcf services, where do you inject the dependency, and how do you test that interaction?
I feel that I'm missing something..
Try having a Func<IServiceClient> injected into your VM instead of the a client instance; you'll have a 'language-level factory' injected instead of building a class for this. In the factory method you can instantiate your client however you want (each access could create a new instance for that for example).
The downside is that you'll still have to touch your tests for the most part, but I assume it will be less work:
public ViewModelExample(Func<IServiceClient> factoryMethod)
{
var client = factoryMethod();
client.DoWorkCompleted += ...
client.DoWorkAsync();
}
The WCF service should have it's own tests that confirm the functionality of itself.
You should then be mocking this WCF service and writing unit tests within your consumers.
Unfortunately, it's a pain and something we all have to do. Be pragmatic and get it done, it will save you getting bitten in the future.
Are you using IoC container by a chance? If you had, this problem would be totally mitigated by container (you'll simply register IService dependency to be created as brand new upon each request).
If that's not the case, then
I would have to write mocks for both the factory and the wcf client every time
is how you deal with this kind of "problems". The cost is relatively small, probably 2-3 extra lines of code per test (all you have to do is setup factory mock to return service mock, which you do need either way).

Making WCF OperationContext play nicely with DI and testing

I'm running a WCF service hosted in a Windows service; dependencies of the WCF service are injected via Unity, which is all good. As a result, the service is also easy to write unit tests for.
Recently, I added functionality to the service that makes use of the OperationContext to inspect incoming messages. Unfortunately this rather blows the testability of the service out of the water, owing to Microsoft's fondness for sealed and/or static classes and lack of interfaces and/or virtual methods.
So I turned to the .NET'ers favourite tool in this situation, a wrapper class. Since this is a common problem, someone's already done the hard work for us. So this adds a new dependency to my WCF service, an implementation of IOperationContext. This was no problem for my unit tests, NSubstitute is my mock framework of choice (like Moq, but without the curse of the .Object).
However, when I try to fire up the service for real, I have the following problem - the OperationContext which is being wrapped has not been initialised at the time the IoC container registrations are done. My initialisation code (using Unity here) is:
container.RegisterType<IOperationContext, OperationContextWrapper>(new InjectionConstructor(OperationContext.Current));
but at this point, OperationContext.Current is null, so Unity promptly throws an exception, and my dreams of retiring before 40 go up in smoke.
So, the question is: how do you get WCF to play nicely with DI and a wrapped OperationContext?
Maybe I'm not understanding, but I'm not sure why you want to inject OperationContext.Current into your wrapper. If OperationContextWrapper is wrapping OperationContext, than why not just have it's implementation interact directly with OperationContext.Current where it needs to? I presume the code you're trying to keep testable is not OperationContextWrapper, but rather the code that depends on it via the IOperationContext interface? Then who care what OperationContextWrapper does?
OperationContext.Current is a settable property. Can you change your test initialization to
OperationContext.Current = new OperationContextWrapper();
and have it work that way? If you need it in unity, you could also:
var oc = new OperationContextWrapper();
OperationContext.Current = oc;
container.RegisterInstance<IOperationContext>(oc);
You can also use Microsoft Fakes :
using (ShimsContext.Create())
{
ShimOperationContext shimOperationContext = new
ShimOperationContext(); shimOperationContext.SessionIdGet = () => "sessionId";
OperationContext.Current = shimOperationContext;
}