iOS: how to do indeterminate asynchronous unit test with GHUnit? - ios

I use GHUnit for unit testing, and wrote subclasses of GHAsyncTestCase, but in my case, the web service is not like an active service request where you send request and expect to receive an answer, instead of this, my web service is a passive type service where you subscribe to a channel then it can send you message, but there is no guarantee about how frequent the server pushes messages to subscribers, in this case, say 50 secs after subscribing, server pushes a message and another message after 30 secs, then should I do:
[self waitForStatus:kGHUnitWaitStatusSuccess timeout:50.0f];
to verify the first message, or is there any smart way for doing this?
Thanks!

It depends on what you want to do.
If you want to verify the data coming from your server, you can send a request to the server to ask it push something immediately and use
[self waitForStatus:kGHUnitWaitStatusSuccess timeout:50.0f];
to wait for the pushed messages.
It you want to verify your objective-c code, you can send some fake data to your object.
If you are using NSURLConnection to get your data, call the delegate method below with some fake data in your testing code
- (void)connection:(NSURLConnection *)aConnection didReceiveData:(NSData *)data
The idea behind unit testing is "unit" testing. The testing code should focus on the "unit" you want to test. It is a good practice to exclude other uncontrollable factors (like network availability) from your testing.

Related

Get response of message queue inside rails controller

I have a rails controller (say in application A) whose response is dependent on data from another application (say application B).
I am using RabbitMq for inter application communication.
I can not render a response from the controller till the time the queue worker gets a response from application B. So currently when I get an HTTP call on application A, I publish to application B through a RabbitMq queue to fetch the required data. I am listening for the response of application B on a queue created by 'sneakers' gem. I want to receive this fetched data from 'sneakers' queue inside the controller of application A.
So the question is how can I wait for the RabbitMq, queue response inside the controller?
And also if I am able to wait for the response inside controller, how will I figure out which queue response is for which HTTP call.
To address the second issue, you can send a randomly generated string along with the request you send to application B. And the application B while responding will also send the same string that it got with the request. So the controller A will know for which request the response is.
Now coming to the first question, I think rabbitmq is not the correct tool to do such a thing. Even if you could wait for the message, It will be a very slow affair. compared to that a better way would be to expose application B as an API. It will increase the speed of the application by many times.
If API is not an option you can look at this link on how to create a consumer.

iOS REST design pattern advice

I’d like some input on whether there is a better design pattern to use for my iOS app, which uses a REST model to communicate asynchronously with a Django back end.
The server can presently return three types of responses to requests:
a JSON object
a server status code integer
a long Django error message
When an action is performed in the iOS app that requires data from the server, my design pattern looks like this:
An observer is added to notification center, specifying a method that can process the server response
The method puts together and sends a NSURLConnection
A NSURLConnection delegate method receives the response, does some interpretation to check what kind of server response it is, and then posts the appropriate notification to the notification center
This triggers the response method to run, processing the response
My issue with this pattern is that there are a large number of methods written to send and receive individual request and response types. For instance, if I am requesting an item list, I need to add several observers to the notification center, one to process a user list, one to process a blank user list, and one to process errors. Then I need to write custom methods for each one of those three to perform the appropriate actions and remove the observers, based on what kind of response the server sends.
Furthermore, the NSURLConnection delegate ends up being fairly complex, because I’m trying to interpret what type of a response was received (what types of items were in the list received?) without much context of what was requested, to make sure I don’t call the wrong response method when a server message comes back.
I am fairly new to both iOS programming and to REST programming, so I may be missing something obvious. Any advice or links to resources is appreciated.
I'd initially look at using RestKit to abstract your code away from the network comms so you can worry more about the data model and high level requests. Secondly, I wouldn't use notifications for this as it will likely get messy and be very hard to manage multiple simultaneous requests - delegation or block callbacks will be much better for this.
Your REST implementation is mostly server side, and emprirically you'd be passing and receiving binary. There are factors to consider, including whether you are utilizing HTTP.
Working with JSON with NSJSONSerialization class, and NSURLConnection keeps your program more lean and mean.

How can you use OCMock with NSURLConnection/delegate for a series of mock network connections?

I've implemented the code in this posting:how to unit test a NSURLConnection Delegate?
and have managed to get a test case going with my code where I simulate sending a server package of data via the mock classes.
This is ok to test a simple single client post / server response type situation but I want to test a conversation scenario where my code makes a post, the server sends a reply, my code makes another response, the server sends another reply etc.
Has anybody done anything similar to this?

Canceling a request when connection to client is lost

I noticed that in a standard grails environment, a request is always executed to the end, even when the client connection is lost and the result can't be delivered anymore.
Is there a way to configure the environment in such a way that execution of a request is canceled as soon as the client connection is lost?
Update: Thanx fo the answers. Yes - most of the problems I am trying to avoid can be avoided by better coding:
caching can make nearly every page fast
a token can help to avoid submitting something twice
but there are some requests which still could consume some time. Let's take a map service as example. Calculating a route will take some time. One solution to avoid resubmitting the request could be a "calculationInProgress" flag together with a message to the user. But then it is still possible to create a lot of sessions and thus a lot of requests in order to do a DOS attack...
I am still curious: is there no way to configure the server to cancel the request? I used to develop on a system where the server behaved this way and it was great :-)
Probably there is no such way. And I'm sure grails (and your webcontainer) is designed to
accept incoming request
process it on server side
send response
if something happened during phase 2, i'll know about it only on send response phase. Actually you can send data to HttpSerlvetRespone by yourself, handle IOException, etc - but it will be too much low-level way, I think. And it will not help you with canceling your DB operations, while you're preparing data to send.
Btw, it's common pattern to use an web frontend, like nginx, that accepts incomming request and and handle all this problems with cancelled requests, slow requests (i guess it's the real problem?), etc.
According to your comment it is reload and multiple clicks that you are trying to avoid. The proper technique should be to use Grails support for handling multiple form submissions:
http://grails.org/doc/2.0.x/guide/theWebLayer.html#formtokens

How to send many emails via ASP.NET without delaying response

Following a specific action the user takes on my website, a number of messages must be sent to different emails. Is it possible to have a separate thread or worker take care of sending multiple emails so as to avoid having the response from the server take a while to return if there are a lot of emails to send?
I would like to avoid using system process or scheduled tasks, email queues.
You can definitely spawn off a background thread in your controller to handle the emails asynchronously.
I know you want to avoid queues, but another thing i have done in the past is written a windows service that pulls email from a DB queue and processes it at certain intervals. This way you can separate the 2 applications if there is a lot of email to be sent.
This can be done in many different ways, depending on how large your application is and what kind of reliability you want. Any of these ways should help you achieve what you want (in ascending order based on complexity):
If you're using IIS SMTP Server or another mail server that supports a pickup directory option, you can go with that. With this option, instead of sending the emails directly, they are saved first in the pickup directory. Your call will immediately return after the email is saved in the pickup directory, so the user won't have to wait until the email is sent. On the other hand, the server will try to send the email as soon as it's saved in the pickup directory so it's almost immediate (just without blocking the call).
You can use a background thread like described in other answers. You'll need to be careful with this option as the thread can end unexpectedly before it finishes its job. You'll need to add some code to make sure this works reliably (personally, I'd prefer not to use this option).
Using a messaging queue server like MSMQ. This is more work and you probably should only look into this if you have a large scale application or have good reasons not to use the first option with the pickup directory.
There are a few ways you could do this.
You could store enough details about the message in the database, and write a windows service to loop through them and send the email. When the user submits the form it just inserts the required data about the message and trusts the service will pick it up. Almost an email queue which you said you didn't want, but you're going to end up in a queue situation with almost any solution.
Another option would be to drop in NServiceBus. Use that for these kinds of tasks.
I typically compile the message body and store that in a table in the db along with the from and to addresses, a subject, and a timestamp indicating when the email was sent. Then I have a background task check the table periodically and pull any that haven't been sent. This task attempts to send each email and updates the timestamp accordingly. One advantage of storing the compiled message body up front is that the background task doesn't have to do any processing of context-specific data, and therefore can be pretty darn simple.
Whenever an operation like is hingent upon an event, there is always the possibility something will go wrong.
In ASP.NET you can spawn multiple threads and have those threads do the action. Make sure you tell the thread it's a background thread, otherwise ASP.NET might way for the thread to finish before rendering your page:
myThread.IsBackground = true;
I know you said you didn't want to use system process or scheduled tasks, but a windows service would be a viable approach to this as well. The approach would be to use MS Queue, or save the actions needing to be done in a DataBase table. Then have a windows service check every minute or so and do those actions.
This way, if something fails (Email server down) those emails / actions can still be done.
They will also be recorded for audit's (which is very nice to have).
This method allows you're web site to function as a website while offloading these tasks to another service. The last thing you need is for multiple ASP.NET processes to be used up waiting for emails to send. let something else handle that.

Resources