Unit testing web service methods - c#

I am currently writing an application which is kind of a proxy between the end-user and a web service.
The user requests a service, and the application calls the web service method with appropriate parameters set, and returns the result.
To make sure nothing went wrong, I have decided to create unit tests for the project (Yep! I know it's a bit late to do it after writing the code. I'll write the unit-tests first next time).
in these unit tests, I have to make real requests to the web service to be sure no permission exception, service-related exception, etc is raised. Therefore extracting an interface and mocking the service for testing is not going to help. Is it acceptable to write unit tests, that actually call the real web service?
Is it possible to have a delay between two tests if my web service just allows for example one request per minute?

What you are speaking about is integration test.
It's not a problem to write such tests for your web service. They are written in the same style as unit test but testing live system and or it's parts. You can even start your web service in your test context.
And it's up to you and your test context to limit situations with call delays or simulate any other situation.

My understanding is that unit tests are supposed to yield immediate result. What you are after is integration tests, not unit tests.

It is acceptable of course, although they would me more "integration tests" than unit tests, since you are testing your whole system integrated.
What you can do to delay the tests, is to simply put a Thread.sleep(1000) in the beginning of the test.

What about testing the code behind the web service layer? What I have done in the past is using web services as merely wrappers to a business logic library where all the real code lives. Then you can do integration tests on this library without worrying about your web service request limits.

Related

How should I assert in WebAPI integration test?

I'm writing integration tests for Controller classes in my .NET Core WebAPI, and honestly, I'm not sure if Assert.Equal(HttpStatusCode.OK, response.StatusCode); is enough. I'm using my production Startup class with only database different (using InMemory database).
This is one of my tests, named ShouldAddUpdateAndDeleteUser. It's basically:
Send POST request with specific input.
Assert If POST worked. Because POST sends respond with created object, I can Assert on every property and if the Id is greater then 0.
Change the output a little bit and send Update request
Send GET request and assert if update worked.
Send DELETE request
Send GET request and assert if null.
Basically, I test, ADD,UPDATE,DELETE,GET (when item exists), GET (when item doesn't exists).
I have a few questions:
Is it a good practice to have such tests? It does do a lot, but it's not a unit test after all. If it fails, I can be pretty specific and specify which part didn't work. Worst case scenario I can debug it pretty quickly.
Is it integration tests or functional test or neither?
If this is wrong, how can I test DELETE or UPDATE? I'm kinda forced to call GET request after them (They return NoContent)
(Side note: It's not the only test I have for that controller obviously. I also have tests for GET all as well as BedRequest requests)
Is it a good practice to have such tests? It does do a lot, but it's not a unit test after all. If it fails, I can be pretty specific and specify which part didn't work. Worst case scenario I can debug it pretty quickly.
Testing your endpoints full stack does have value but make sure to keep in mind the testing pyramid. Its valuable to have a small number of full stack integration to validate the most important pathways/use cases in your application. Having too many however, can add a lot of extra time to your test runs which could impact release times if those tests are tied to releasing (which they should be).
Is it integration tests or functional test or neither?
Without seeing more of the code I would guess it's probably a bit of both. Functionally, you want to test the output of the endpoints and it seems as though you're testing some level of component integration if you're mocking out data in memory.
If this is wrong, how can I test DELETE or UPDATE? I'm kinda forced to call GET request after them (They return NoContent)
Like I said earlier, a few full stack tests are fine in my opinion as long as they provide value for major workflows in your application. I would suggest one to two integration tests that make database calls that make sure your application can stand up full stack but not bundle that requirement for your functional testing. In my experience you get way more value from modular component testing and a couple end to end functional tests.
I think the test flow you mentioned makes sense. I've done similar patterns throughout my services at work. Sometimes you can't realistically test one component without testing another like your example about getting after a delete.

Unit testing http requests to rest api

I have a C# library that gets data from public api.
trying to get into TDD and was wondering how to unit test a library that the main focus of it is to get data from the server and convert the json to .net objects. (Basically handling the http requests along with limiting and error handling and some configuration settings)
I know you should mock some sort of database but not sure how exactly. And i've read that the tests should run all the time even with internet connection off.
You can implement only integration testing. You also can test your code with internet connection off - just create a kind of wrapper. Among various design patterns the most appropriate is Facade for this kind of task. Create Facade around third-party library so you can mock this facade in future and make it produce desired/undesired results so you can unit test your classes. But:
Don't test or mock what you don't own

Purpose of WCF mocking

I am having difficulties while trying to understand the purpose of mocking my WCF applications in unit tests. I have read this article Testing with mock objects and I believe I got the idea why we use mocking in standard application - it is better to test behaviour rather than implementation of the method. So with using Mock objects, I can test whether certain method called certain mock object, whether it changed some properties etc.
But while I was searching for some good ways how to test WCF, everyone was suggesting to use Mocking as well. The thing is, that I feel like I should test whether method (which is communication with service) is really able to reach the service and obtain result, that is satisfactory...which is not the case I will achieve using mock object.
Question:
Is using mock objects in my WCF app unit tests really intended to test only whether the method tried to call the OperationContract(method) exposed by service (while not expecting the real results)?
Or am I missing something?
The purpose of Unit Testing is not to test your application, but to make sure the code you've written is doing what is intended and subsequently let you know when you've made a simple coding goof. When it comes to testing for communication-based services, there are a dozen other factors, not the least of which being actual connectivity, that could affect your connection but not actually tell you anything useful about your code. Thus, you should rely on running debug runs of your application to test end-to-end functionality, and Unit Tests with those mocks to test the actual code functionality.
Will you miss something here and there? Yes, but the definition of good Unit Tests is such that you'll eventually have to touch them up when this happens.

How to write integration/health test of a wcf service on which I have no control?

I need to write a little more than simple test for a service. I have no control over it, but for a specific request it returns specific response that I know it should return.
You could create a project in your solution named YourProject.IntegrationTests and place all tests of this kind in there.
You could use the same tools you use for unit testing to create your test cases (NUnit, XUnit, MSTest, etc)

How to unit test C# Web Service with Visual Studio 2008

How are you supposed to unit test a web service in C# with Visual Studio 2008? When I generate a unit test it adds an actual reference to the web service class instead of a web reference. It sets the attributes specified in:
http://msdn.microsoft.com/en-us/library/ms243399(VS.80).aspx#TestingWebServiceLocally
Yet, it will complete without executing the test. I attempted to add the call to WebServiceHelper.TryUrlRedirection(...) but the call does not like the target since it inherits from WebService, not WebClientProtocol.
What I usually do is not test directly against the web-service, but to try and put as little code as possible in the service, and call a different class which does all the real work. Then I write unit tests for that other class. It turns out that class can sometimes be useful outside of the web-service context, so this way - you gain twice.
If you are writing a web service, try to put all logic in another (testable) layer. Each Web method should have a little code as possible. Then you will have little reason to test the web method directly because you can test the underlying layers.
[WebMethod]
public void DoSomething()
{
hander.DoSomething();
}
If you are consuming a web method, wrap the generated caller in a class wrapper, and implement an interface for the class wrapper. Then, anytime you need to call the web service, use the interface to call the method. You want to use the interface so as to make the class wrapper swappable during testing (using Rhino Mocks, Moq, or TypeMock).
You can add a service reference to your unit test project or generate your client stub and put the class in your unit test project.
I had problems with this as well, so i use this workaround:
http://techkn0w.wordpress.com/2009/07/01/unit-testing-an-asmx-web-service-in-visual-studio-2008/
Above my web method unit tests, I have the following:
// TODO: Ensure that the UrlToTest attribute specifies a URL to an ASP.NET page (for example,
// http://.../Default.aspx). This is necessary for the unit test to be executed on the web server,
// whether you are testing a page, web service, or a WCF service.
[HostType("ASP.NET")]
[UrlToTest("http://localhost/MyWebService")]
In addition to the usual:
[TestMethod()]
[DeploymentItem("MyWebService.dll")]
This code came about from using the Visual Studio 2008 Unit Test Wizard.
Know that there are two types of Web Service. Those you write yourself and want to test, and those that you consume. For the former, the above rules apply. However, I would say that sometimes I see developers testing against external web services. Logic dictates that a third party service is unreliable and therefore requires much more testing. In object-oriented programming, it is best to understand the separation of concern that Martin Fowler and the others all told us about. This means that we should not test systems external to our own.
However, I like to write wrapper classes to provide useful functionality against the services. For example, Bing Maps has a number of amazingly powerful functions. I write tests against these just to ensure that they give me the expected values. Although not extensive, the point of them is that if the web service dies for any reason (authentication key expires, etc) then I can be informed of it via the Test Server.

Categories

Resources