Using Assert::ExpectException with Native Unit Testing in VS11


 

The native unit testing capabilities in VS11 beta are very cool indeed.  Being mainly a managed code developer, I was left wondering how to pass a test if an expected exception is thrown (a al the [ExpectedException] attribute I’ve used with MS-TEST in managed code unit tests.  With the native unit testing capabilities in VS11, there is no ExpectedException attribute, but there is a static Assert::ExpectException method that we use to verify that our code under test throws an exception.  It accepts a lambda or a functor as a parameter.  Being a beta, I hadn’t seen too many examples, so I’ve included a couple below.

 

   1:          TEST_METHOD(ExpectCallThrowException)
   2:          {
   3:              auto func = [this] { throwException();};
   4:              Assert::ExpectException<int>(func);
   5:          }
   6:   
   7:          void throwException()
   8:          {
   9:              throw 1;
  10:          }
 
 

Here is a more realistic example, where my BankAccount class throws an invalid_argument exception if a zero amount is passed in as the parameter.

   1:  double BankAccount::Debit(double amount)
   2:  {
   3:      if(amount == 0)
   4:      {
   5:          throw std::invalid_argument("amount");
   6:      }
   7:      balance -= amount;
   8:      return balance;
   9:  }
  10:   
  11:  double BankAccount::Credit(double amount)
  12:  {
  13:      if(amount == 0)
  14:      {
  15:          throw std::invalid_argument("amount");
  16:      }
  17:      balance += amount;
  18:      return balance;
  19:  }

And for my test code, we have examples below of using Assert::ExpectException with a lambda, or by catching the exception ourselves and verifying in the test.

   1:      
   2:  #include <stdexcept>
   3:  #include <functional>
   4:   
   5:          TEST_METHOD(InvalidArgumentIsThrownWhenDebittingZero)
   6:          {
   7:              BankAccount* sut = new BankAccount();
   8:              double amount = 0.00;
   9:              function<double (void)> f1 = [sut] { return sut->Debit(0.00); };
  10:              Assert::ExpectException<invalid_argument>(f1);
  11:          }
  12:   
  13:          TEST_METHOD(ExceptionThrownWhenCreditAmountIsZero)
  14:          {
  15:              BankAccount* sut = new BankAccount();
  16:              double amount = 0.00;
  17:              bool exceptionThrown = false;
  18:              try
  19:              {
  20:                  sut->Credit(amount);
  21:              }catch(invalid_argument& ex)
  22:              {
  23:                  auto desc = ex.what();
  24:                  exceptionThrown = true;
  25:              }
  26:              Assert::IsTrue(exceptionThrown);
  27:          }

I haven’t seen too many examples of using Assert::ExpectException, so hopefully this is helpful.  If this all changes for the VS11 RTM, I’ll be sure to update this post.

Thanks,
-Dan


Comments (2)
  1. Bill E says:

    Thanks!  This was very helpful.

  2. Sergios says:

    Here my test method:

    TEST_METHOD(TestInputGetValueOutOfRangeIndex){

    std::vector<float> inputs;

    inputs.push_back(5.0f);

    Input *input = new Input(inputs);

    auto funcPtr = [input]{ input->getValue(2); };

    Assert::ExpectException<IllegalArgumentException>(funcPtr);

    }

    here my mehtod:

    float Input::getValue(unsigned int valueIndex)

    {

    if(valueIndex>=_values.size()){

    throw new IllegalArgumentException("Input Class: valueIndex is out of range");

    }

    return _values[valueIndex];

    }

    can sbdy help me?

    Thanks

Comments are closed.

Skip to main content