locked
ASYNC Test Method not catching OperationCanceledException thrown by method under test? RRS feed

  • Question

  • Running VS 11 Beta and using MSTest (Win7 x64). I'm throwing an exception in the method under test, but the try/catch in the test doesn't catch it -- nor will the use of the ExpectedException attribute. In fact, if I put a breakpoint on the last Assert of the test it never gets reached!

    Here's the test:

        [TestMethod] //[ExpectedException(typeof(OperationCanceledException))]
        public async void TestUncaughtOperationCancelledException()
        {
          var instance = new AsyncOperations();
          CancellationTokenSource tokenSource = new CancellationTokenSource();
          tokenSource.Cancel();
          Task op1Task = instance.DoOperation5(tokenSource);
          try
          {
            await op1Task;
          }
          catch(OperationCanceledException ex)
          {
            Assert.AreEqual(TaskStatus.Canceled, op1Task.Status, "Task not cancelled as expected");
          }
          Assert.AreEqual(TaskStatus.Canceled, op1Task.Status, "Task not cancelled as expected");
        }
      


    Here's the method under test:

        public async Task DoOperation5(CancellationTokenSource tokenSource)
        {
          await Task.Delay(1000);
          tokenSource.Token.ThrowIfCancellationRequested();
    
        }
    

    Is this a threading problem; i.e., the test is being run on a different thread than the method under test? What's going on here?

    Thanks for any guidance or advice.

    Bill


    Bill Cohagan

    Tuesday, May 8, 2012 10:57 PM

Answers

  • Hi Bill,

    Thanks for using Visual Studio 11 and giving feedback.

    Async testmethod must return Task to work properly. Please change your method as follows and it should work:

        [TestMethod]
        public async Task TestUncaughtOperationCancelledException()
        {
          var instance = new AsyncOperations();
          CancellationTokenSource tokenSource = new CancellationTokenSource();
          tokenSource.Cancel();
          Task op1Task = instance.DoOperation5(tokenSource);
          try
          {
            await op1Task;
          }
          catch(OperationCanceledException ex)
          {
            Assert.AreEqual(TaskStatus.Canceled, op1Task.Status, "Task not cancelled as expected");
          }
          Assert.AreEqual(TaskStatus.Canceled, op1Task.Status, "Task not cancelled as expected");
        }
    

    In our latest code we fixed the warning, and in future builds you should get a warning when returning void from async testmethod.


    Regards,
    Vikram Agrawal,
    Developer, VSTLM, Microsoft Corporation

    • Marked as answer by Bill Cohagan Wednesday, May 9, 2012 1:27 PM
    Wednesday, May 9, 2012 5:21 AM