Logic need to checked in Unit test cases method - unit-testing

I have a GET method for webAPI which returns say hundred Products list. What logic should one need to check to diagnose the test as pass or fail?
Should I check for count>0 or anything else?
Ideally I should not check for product count as it may change (count==100).

Check out these useful links on unit testing with async web requests:
https://codereview.stackexchange.com/questions/85321/unit-testing-http-requests
https://msdn.microsoft.com/en-us/library/hh404088.aspx
https://codeutopia.net/blog/2015/01/30/how-to-unit-test-nodejs-http-requests/
http://www.jeremyg.net/entry/unit-testing-a-fetch-api-service-in-aurelia
http://lazamar.github.io/testing-http-requests-with-jasmine/
Why should I mock HTTP requests inside unit tests?
Suppose your client component has a variable count that it initialized to 0. Then you fire some web request, and it responds with data like this:
{
response: 500
}
where response can have any whole number value. Then count gets set to the value of response.
The basic gist of this unit test would be to mock the actual calling to the server (instead of making the api call and return the response, just return a hardcoded object). Then assert that the "count" variable is as you would expect it to be from this predefined response. You can then set up multiple cases (ie multiple tests) for each possible type of response that can be returned. Good luck!

Related

Accessing request container (event_dispatcher) within a test client

I created a simple test case in Symfony.
So one client which should listen for an event which will be dispatched during an request.
But nothing happen because the request have an own scope or I dont know why Im not able to access the dispatcher in it.
$this->client = static::createClient();
self::$container = $this->client->getContainer();
$dispatcher = self::$container->get('event_dispatcher');
$dispatcher->addListener('example', function ($event) {
// Never executed
});
$this->client->request('POST', $endpoint, $this->getNextRequestParameters($i), [$file], $this->requestHeaders);
$this->client->getResponse();
The listener is never called.
When I debug it a bit I find out that the object hash via spl_object_hash($dispatcher) is different on the highest level than on within the request level.
So it seems that the request has an own world and ignores everything outside.
But then is the question how I can put my listener to this "world"?
I think part of the problem is the mixing of testing styles. You have a WebTestCase which is intended for a very high level of testing (requests & responses). It should not really care about internals, i.e. which services or listeners are called. It only cares that given input x (your request) you will get output y (your response). This allows to ensure the basic functionality as perceived by your users is always met, without caring how it is done. Making these tests very flexible.
By looking into the container and the services you are going into a lower level of testing, which tests interconnected services. This is usually only done within the same process for the reasons you already found out. The higher level test has 2 separate lifecycles, one for the test itself and one for the simulated web request to your application, hence the different object ids.
The solution is either to emit something to the higher level, e.g. by setting headers or changing the output, so you can inspect the response body. You could also write into some log file and check the logs before/after the request for that message.
A different option would be to move the whole test into a lower level where you do not need the requests and instead only work with the services. For this you can use the KernelTestCase (instead of the WebTestCase) and instead of calling createClient() you call bootKernel. This will give you access to your container where you can modify the EventDispatcher. Rather than sending a request you can then either call the code directly, e.g. dispatch an event if you only want to test the listeners, or you can make your controller accessible as service and then manually create a request, call the action and then either check the response or whatever else you want to assert on. This could look roughly like this:
public function testActionFiresEvent()
{
$kernel = static::bootKernel();
$eventDispatcher = $kernel->getContainer()->get('event_dispatcher');
// ...
$request = Request::create();
// This might not work when the controller
// You can create a service configuration only used by tests,
// e.g. "config/services_test.yaml" and provide the controller service there
$controller = $kernel->getContainer()->get(MyController::class);
$response = $controller->endpointAction($request);
// ...Do assertions...
}

httptest.NewRequest vs http.NewRequest: which one to use in tests and why?

Golang has these two similar libs http and httptest and they both have the NewRequest func.
Why do we even need the httptest.NewRequest if http.NewRequest does it all?
If I need to create a multipart/multiform request for my tests, which one do I need to use?
As indicated in the documentation, httptest.NewRequest "returns a new incoming server Request, suitable for passing to an http.Handler for testing", while http.NewRequest "returns a Request suitable for use with Client.Do or Transport.RoundTrip." So, if you're passing the request directly to the handler in a unit test, use httptest.NewRequest, and if you're executing a full round-trip using http.Client, use http.NewRequest.

How to unit test Spring Integration flow - specifically http outbound gateway

I wonder if anyone can help - this has been driving me crazy for days!
I have a fairly simple Spring Integration file that I'd like to unit test. The SI uses an http outbound gateway, and I specifically want to unit test rather than integration test - I do not want to provide a mock http server using something like Spark or MockRestServiceServer.
My SI config looks like this:
<int:channel id="modifiedAttractionChannel" datatype="u.o.n.p.i.a.s.AttractionUuid">
<int:interceptors>
<int:wire-tap channel="attractionModifiedChannelLogging"/>
</int:interceptors>
</int:channel>
<int-http:outbound-gateway
id="serviceGateway"
request-channel="modifiedAttractionChannel"
url="/attractions/{uuid}"
http-method="GET"
expected-response-type="u.o.n.p.i.a.v.m.Attraction"
charset="UTF-8"
reply-timeout="${vader.reply.timeout}"
request-factory="clientHttpRequestFactory"
reply-channel="vaderAttractionChannel">
<int-http:uri-variable name="uuid" expression="headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value" />
</int-http:outbound-gateway>
<int:channel id="attractionChannel" datatype="u.o.n.p.i.a.v.m.Attraction">
<int:interceptors>
<int:wire-tap channel="vaderAttractionChannelLogging"/>
</int:interceptors>
</int:channel>
<int:logging-channel-adapter
id="attractionModifiedChannelLogging"
expression="'attractionModifiedChannel: header=' + headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value + ', payload=' + payload"
level="INFO" />
<int:logging-channel-adapter
id="vaderAttractionChannelLogging"
expression="'attractionModifiedChannel: header=' + headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value + ', payload=' + payload"
level="INFO" />
I have written a unit test that wires up a basic spring context and am able to get the modifiedAttractionChannel and send an appropriately built Message with an AttractionUuid payload and header value.
My unit test can assert that the log message written to attractionModifiedChannelLogging is as I expect it (I created the AttractionUuid and Message, so I know the payload and header values)
What I now need to do is assert the value written to the vaderAttractionChannelLogging wiretap. IE. I need to assert a message with a given header value - no problem, I created the header value as part of the test - but also the payload.
In this case the payload is the output of the outbound gateway. Given that this is a unit test and I don't want any dependency on anything else, I have provided a mock ClientHttpRequestFactory which in turn provides a mock ClientHttpResponse via a mock ClientHttpRequest
This works great in that I can control the response body that the outbound gateway would otherwise receive. However, the RestTemplate calls its HttpRequestExecutingMessageHandler in order to convert the response body into an object via the MessageConverters
Whilst this works in respect of the execution of the SI flow, it means the instance of Attraction that is on the reply-channel vaderAttractionChannel is not in control of the test; and therefore I cannot make any assertions about it in respect of what gets logged on the vaderAttractionChannelLogging wiretap.
I think one way of addressing this is to be able to wire in a mock or stub MessageConvertor instead of the standard set that returns a fixed Attraction instance. But I can't for the life of me work out how to!
Note: The scenario above is a much simplified version of what I'm actually trying to do. I'm not really trying to write unit tests around logged values! I need to test the overall flow of my SI, and being able to control the instance of the Attraction that the outbound gateway returns is very much key to that.
Any help with this would be very much appreciated;
Cheers
Nathan
It's not clear what your issue is; "...the RestTemplate calls its HttpRequestExecutingMessageHandler..." - it's actually the other way around. If you really want to unit test the flow, you should provide a normal result from the mock that will be converted by the standard converters. If you really want to mock the conversion too, use the message-converters attribute.

Writing Unit Tests with ODataQueryOptions

I am new to writing test cases for WebAPI's. I have seen similar questions asked in the past, but not answered, but I am wondering how I would test my APIs if they have an ODataQueryOptions as part of the parameters. See below:
public IQueryable<Item> GetByIdAndLocale(ODataQueryOptions opts,
Guid actionuniqueid,
string actionsecondaryid)
Would I have to moq this? If so, how would this look? Any help would be appreciated.
For ODataQueryOptions perspective, you may want to test that all the OData query options can work with your Function. So firstly you need to create an instance of ODataQueryOptions. Here is an example:
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);
ODataQueryContext context = new ODataQueryContext(EdmCoreModel.Instance, elementType);
ODataQueryOptions options = new ODataQueryOptions(context, request);
So you need to create your own EDM model to replace EdmCoreModel.Instance, and replace requestUri with your query. elemntType in ODataQueryContext is "The CLR type of the element of the collection being queried".
I cannot tell from the phrasing, but is the above call (GetByIdAndLocale) the Web API that you are trying to test or are you trying to test something that is calling it?
One uses a mock or a stub to replace dependencies in a Unit Under Test (UUT). If you are testing GetByIdAndLocale() then you would not mock it though if it calls something else that takes the ODataQueryOptions as a parameter, you could use Moq to stub/mock that call.
If you are testing some unit that calls GetByIdAndLocale() then, yes, you could moq it. How exactly you might do this depends upon the goal (checking that the correct values are being passed in vs. checking that the returned IQueryable is correctly processed) basically, matching against It.IsAny() or against some matcher.
Which do you want to test?
GetByIdAndLocale(), something that calls it or something (not shown) that it calls?
What are you interested in verifying?
Correct options are passed in or the processing of the return from the mocked call?

Unit test for web service (Service Reference) - xml deserialization

In Summary
I need a way to deserialize an XML string into an object normally returned by a 3rd party webservice.
Using C#.
In Detail
I have code that consumes a 3rd party Service Reference (Web Service) - so the usual stuff: we pass in a Request object and it returns a Response object.
Regarding unit testing - I'm not interested in the inner workings of the Service Reference since this is a 3rd party service. I'm only interested in two things:
Does my code generate the correct Request object?
When the Service Reference returns it's response, do I process this response correctly?
Taking each in turn:
Does my code generate the correct Request object?
This I can do. If anyone's interested in this, what I do is to replace my service reference with a RhinoMocks Mock object. In my unit test I call the method on my Mock and then check the arguments passed in, comparing the actual Request object against the expected Request object.
When the Service Reference returns it's response, do I process this response correctly?
What I want to do here is to create a RhinoMocks Stub of my service reference, so that when it's called this stub returns a response object populated with my test data.
The problem that I face is that the response objects returned by this particular 3rd party service are extremely complex. If I were to attempt to create one by hard-coding all the property values by hand then this would probably take me the best part of a whole day.
However, what I can very easily do is to capture the XML serialized response from this service. I could then easily edit it's values and store this XML in one of my unit tests.
What I'm after is an easy way to then "deserialize" this "test" XML into a response object and use this to program the response from my Stub.
Any help would be much appreciated.
Thanks
Griff
Turns out that this is quite simple:
public static object Deserialize(string xml, Type toType)
{
using(Stream stream = new MemoryStream())
{
byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
stream.Write(data, 0, data.Length);
stream.Position = 0;
var s = new XmlSerializer(toType, "http://^your url^");
return s.Deserialize(stream);
}
}
Note that if you're using XML from a SOAP request, strip the SOAP envelop off first.
Griff