I'm designing an enterprise level web app that will have a Data layer + SQL database, a WCF REST web service layer that communicates with the data layer, then an MVC website which will communicate to the WCF REST web services. I want to have automatic unit testing at each level of the design.
I have created a data layer unit test project fine, which tests the EF models, repositories, operations etc and have about 15 tests I can click a button for and run which so far, tests all the functionality the data layer provides.
I want to have the same at the WCF service layer but I cannot figure out how to have an automatic test project to run against a WCF service. I've seen articles on using WCF test client to load the service in the background and be able to input parameters to each service method and see results, but I don't want a manual process, I want it to be automated, to mock the data layer and test the service calls in isolation. Complicated by the fact that ideally I would like to test the RESTful side of it, so being able to simulate GET/POST/PUT/DELETE etc and also to call certain methods with the wrong method and to confirm it fails as expected and so forth.
Is there a good solution to do this automatically or am I approaching this wrong?
You sure can create tests that can automatically run to test WCF services.
See SO discussion here:WCF Unit Test
However one question you need to ask in your test strategy / test case design is that howmuch of the REST endpoint testing need to be unit tests and how much need to be part of system/ integration test. Because the wcf endpoints (including REST) will allow you to treat the system as a black box and do system tests without having any intimate knowledge of the internal types.
I wrote an article on how to do that. You have to abstract the business logic to a service which either calls the real service or a mocked one. http://gaui.is/how-to-mock-and-test-wcf-services-using-moq/
you can change the address of the service to localhost.
this way you can start the service and test it with no mocking
Related
we have a azure mobile service implemented for one cross platform mobile app. We have used azure mobile services to expose the back end to mobile apps.
All the controllers we are using extending table controller and most of the service methods has some custom logic implemented. Now we wanted to unit test these custom logic.
Is there any way we can mock table controllers and write unit tests? I have tried everywhere and even i have checked MSDN forums also. I could n't get any info about it. Let me know, if anyone done this and can share a sample.
All the interactions with the backend database are done through the DomainManager, so you are likely to have to moch the EntityDomainManager that you use in your TableControllers when testing. The SDK has a ctor overload for TableController that takes a DomainManager. You could register your mock with Autofac in your tests and have that get used during testing (if you are testing the full pipeline). If you are hitting the TableController in isolation with new YourController(), you can just use that overload to pass in your mocked DomainMAnager and make sure you don't create a real DomainManager in Initialize.
I'm looking at converting an existing web service into a Web API. I've only worked with a WS a little bit and it was a long time ago. What I do remember is that in my project I would make reference to a service location and then use that reference to call whatever method I needed.
EX: I would reference http://mydomain/webservicename/mobile.asmx and then would call objWS.MethodName() what was coded within the mobile.asmx file.
If I convert over to using a Web API I would basically call the HTTP by going to something like http://mydomain/controllername/myMethod.
As of right now I don't have access to the client code to be able to change the way that it calls the service. That being said am I stuck with using a traditional web service vs web api?
This is an app on a handheld scanner that I believe is running Windows CE. We are having some connectivity issues/database deadlocks and I was asked to look at it and see if I can help out. The current WS code is overly complicated IMO since it's only doing either an insert or an update to a database. I would also think that going with a Web API would make it a faster app since it's depending on cellular access for it's communication. JSON should be a smaller payload than XML.
So, I would like to just re-write it using Web API 2 and Entity Framework. However, I'm afraid I'm stuck to using WS since I don't have access to the client code.
Any suggestions?
It's a fairly broad architectural suggestion, but what you're proposing certainly sounds possible and even quite reasonable.
If I understand correctly, you currently have this:
Client -> ASMX Service
And you can't change the Client, only the ASMX Service. The first thing you're going to want to do this ensure that server-side business logic is de-coupled from the platform technology:
Client -> ASMX Service -> Business Logic
The idea here is that any application host should be able to reasonably invoke the same business logic, even if that logic is nothing more than direct database access. The application host itself should be little more than a pass-through set of operations to be invoked.
At that point, you can create a second application host alongside the first one:
Client -> ASMX Service ----|
|-> Business Logic
WebAPI Service --|
So now you have two different services which expose the same business logic, using two different web service technologies. Each of them should be very thin, as application host technologies should always be easily replaceable.
At this point, assuming there are no significant gaps in the operations available between the two services, you can publish the new service's specifications to clients and begin plans to deprecate the old service. When you can deprecate it is more of a contractual issue than a technical issue. However long you've committed to maintaining it, that's how long clients will have a reasonable expectation to still use it.
If you really want to, you can even have the ASMX Service be a pass-through to the WebAPI Service, but in my personal experience that adds unnecessary layering to the whole setup and artificially complicates the abstraction of the business logic. Either way, the interface exposed by the ASMX Service wouldn't change.
The main thing here is the logical abstraction of the operations being exposed and the analysis of any gaps between what the ASMX Service can do and what the WebAPI Service can do. If that gets complex, then that's an indication that the business logic (and indeed the whole solution domain) is tightly coupled to the application technology being used, namely ASMX web services. That is the problem to be solved. Once solved, creating different application hosts and exposing different services which invoke the same underlying business operations becomes almost trivial.
You are right; you are stuck if you can't change the client and you want to change service protocols. Your client currently has a specific .asmx endpoint it is configured to point to and until you can update that endpoint and have the client stop using the proxy generated from the service, you can't change to Web API.
I'd still rewrite the service to use EF, though.
I have a VS 2010 solution that contains two projects: the first is a WCF service, and the second is a unit testing project, holding a reference to the service and testing the methods the service is exposing. The unit test project is developed using the Microsoft.VisualStudio.TestTools.UnitTesting framework.
Before running the testing project I run locally the WCF service using right clock on the SVC file and choose the option "View in Browser". Only when the service is "up in the air" the tests can actually run.
My question is whether there is an option to run the service automatically before the unit tests start running, using a C# code or some kind of a script?
If you truly want to operate on hosted service, you can self-host it within unit test. Then it will be independent from infrastructure, making it repeatable, so future developers will have ability to run them without making any additional setups.
But think twice, do you want to test service logic or its hosting infrastructure? WCF has decoupled implementation by using contracts (interfaces). You can successfully test service logic by testing service class as any other class, calling web service methods as any other methods.
If your service has an external dependencies (like other services), they should be maintained by Dependency Injection. It will allow you to mock them. If you service relies on global, or static resources (like OperationContext), create a wrapper, that will allow you to inject its mock also. Or use more sophisticated solution like Microsoft Fakes (refer also this tutorial) or Typemock Isolator.
When you will have all logic tested, then you can proceed with integration test with IIS hosted service, testing connectivity to other resources and boundary conditions like timeouts etc.
Install or configure IIS and run the WCF service from a URL on localhost
http://localhost/my.wcf.service
Run your tests from this.
Although, in the strictest sense of the word, running tests on your code via http is an integration test and not a unit test.
We have an application in which we have created a service layer with most of the business logic and utility services (logging, exceptions, caching etc). We have to come with a way to expose this service as an API to the UI components. Here are some of our requirements:
We would like to create multiple
components based on the service.
We would like third party developers
to use our service to create their
own components or utilize our data.
For scalability we would like to have
a multiple instances installed on
different boxes. Similarly there
could be more than an instance of the
same UI component.
One way to expose the service layer is to host it under a REST based WCF layer.
The other way is to host the service in model layer of an ASP.Net MVC project. The UI components will be hosted in MVC projects of their own. The Javascript in the views of UI components will directly call the controllers of service project.
WCF is supposed to be very heavyweight option. On the other hand I am not too convinced with the MVC approach as I feel that this is not purpose it is meant for.
Could you please recommend me a way in Microsoft world to expose our service layer.
WCF seems to be the way to go here. Although WCF started out (in my oppinion) as a beast, it got tamed over the years with better HTTP and JSON support and less custom configuration (although still allowing you to modefy basicly every little aspect of your service).
Exposing your current service layer as a REST Service is a breeze and allows your customers/yourself to easily consume it on any device that supports HTTP.
See: http://codebetter.com/glennblock/2010/11/01/wcf-web-apis-http-your-way/
Models are not services. Models are POCOs that hold data.
You can expose your service through a WCF Service, and let your ASP.NET MVC app consume it. If you're always sure that the service will run on the same box as the client app, you can use named pipes for transport -- then the overhead of WCF is minimal, compared to the advantages.
WCF seems to be the direction that Microsoft is headed for this and for good reason. WCF services are the best option here because you mentioned third-party development support. Because these web services are defined by a WSDL, they are cross platform and can be consumed by non .NET applications.
It perfectly seperates your service layer to be consumed by ANY components.
What is the best way to test web service using NUnit.
I want it to be automated, i.e, I don't want to have a separate process to host the web service for the testing code to consume.
The web service is just a plain-old-.net class. You can instantiate it directly and call its methods in a unit test.
That won't allow you to test http specific aspects of web services like authentication at the protocol level, but I would say that there's no getting around using a web server for that.
It depends on what you want to test. It's possible to do full integration tests and there is some value in that (checking serialization, for instance). One simple way to get good test coverage with minimal work is as follows:
Write one or more plain old classes that do the real work (use TDD if desired)
Test these classes in isolation
Have your WebMethods delegate to these classes.
Depends. If it's an asmx, you can use HostableWebCore on Vista and higher. If it's WCF, just self-host by creating an instance of ServiceHost in your process. You could directly instantiate the service impl, but if you have any HTTP-isms (HttpContext, Request/Reponse access, cookies, etc), you'll have to mock them.