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
Anonymous
September 09, 2013
Thanks! This was very helpful.Anonymous
August 23, 2014
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