chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi,

I'm having difficulty in how to approach testing the following code:

        [WebMethod]
        public IAsyncResult BeginDoingStuff(ComplexObjectRequest request, AsyncCallback callback, object state)
        {
            ComplexObjectResponse response = new ComplexObjectResponse();
            AsyncResult<ComplexObjectResponse> asyncResult = new AsyncResult<ComplexObjectResponse>(callback, state);

            try
            {
                MyWorkerClass wc = new MyWorkerClass();
                wc.LongRunningOperation(asyncResult);

                return asyncResult;
            }
            catch (Exception)
            {
                response.Error = "Error!";
                asyncResult.SetAsCompleted(response, true);
                return asyncResult;
            }
        }

        [WebMethod]
        public ComplexObjectResponse EndDoingStuff(IAsyncResult call)
        {
            try
            {
                AsyncResult<ComplexObjectResponse> asyncResult = (AsyncResult<ComplexObjectResponse>)call;
                ComplexObjectResponse result = asyncResult.EndInvoke();
                return result;
            }
            catch (Exception)
            {
                ComplexObjectResponse result = new ComplexObjectResponse();
                result.Error = "Error!";
                return result;
            }

        }


Within BeginDoingStuff, a call to LongRunningOperation takes place which in this case just performs a Thread.Sleep operation for 10 seconds.

Now, my incomplete test currently looks like:

        [TestMethod(), Isolated]
        public void BeginDoingStuffTest()
        {
            WebServiceUnderTest target = new WebServiceUnderTest(); 
            ComplexObjectRequest request = new ComplexObjectRequest();

            AsyncCallback callback = null;
            IAsyncResult expected = null;
            IAsyncResult actual = null;
            object state = null;
            
            actual = target.BeginDoingStuff(request, callback, state);

            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }


Out of curiosity, I ran the test in order to observe the behavior and it appeared to work correctly; It returns an IAsyncResult object (after 10 seconds) ready to be processed by the EndDoingStuff method.

My question: How can I get the unit test to execute both the Begin and End methods, taking into account the long running process in between?

I suppose the end method could be called after the Begin method has finished processing (in the test), but not sure this is the ideal approach, so I'm open to ideas and suggestions.

Note: I've tried various approaches including some blog posts on Typemock's site i.e. Here and Here, but not been able to achieve the results I want.
asked by garethmonk (1.1k points)

1 Answer

0 votes
Hi,

The best practice is to test each method in a separate test.
To write test for BeginXXX() method you'll need to Assert the return value and the objects that are affected by it.
To write tests to EndXXX() method you'll need to fake the IAsyncResult object that's passed to it as an argument.

In order to run both methods(BeginXXX and EndXXX), you should find the most suitable way for you to stop the main thread while waiting for the other to finish.
One possible way to achieve this is demonstrated in the example that you saw in this blog post.
while (!myHandle.IsCompleted)
makes the main thread "stop".
Another option is to use WaitHandle.WaitOne Method to "stop" the main thread and call EndXXX() after the StardXXX() ends.

Please let me know if it helps.
answered by alex (18k points)
...