Question How does one test a const member function?
Unit test a const subscript operator and get a passing test. In other words can I avoid writing a test; have a compiler throw an error to prove success, then avoid the need to comment the test out to allow proper compilation for the remainder of the tests?
My Attempts: My reasoning was if I test for is_const<>::value and is true I can throw an exception that would be caught by my unit test and allow the test to "Pass" do to failure to change value of element at location of subscript index.
my const subscript definition
#include <type_traits>
// operator [] const
template <typename T>
typename Vector<T>::const_reference
Vector<T>::operator[](size_t index) const {
if (size_ <= index || index < 0) {
throw std::out_of_range("Index out of range.");
}
if constexpr(std::is_const<std::decltype(*this)>::value) {
throw std::runtime_error("Cannot modify elements of a const Vector.");
}
return array_[index];
}
my UnitTest
TEST(SubScriptConst) {
const Vector<int> myVecConst = {0,1,2,3,4,5,6,7,8};
try {
myVecConst[2] = 4; // This will throw an exception?
}
catch (const std::exception& ex) {
std::cout << "SUCCESS | Caught exception: " << ex.what() << std::endl;
}
CHECK_EQUAL(myVecConst[2], 2);
}
The obvious. It does not work. I know its because of my lack of understanding the language. My assumptions are the compiler is checking the value assignment of a const before the code is executed and gives error. If I am able to I will be placing the try block inside a MACRO #ifdef for testing only and still allow the compiler to throw error when not testing.
If a class member function declered as const
then it can't modify any class data members except the class data members which are declered mutable
.
This const
behavior is enforced by compiler and not the C++ runtime. So if someone will try to modify a non-mutable data member in const
member function then it will be a compile time error and not a runtime error. So you can skip writing such test cases.
Following are some related excerpts from in C++ standard:
[Note 1: Thus in a
const
member function, the object for which the function is called is accessed through aconst
access path. —end note]
int s::f() const { return a; }
The
a++
in the body ofs::h
is ill-formed because it tries to modify (a part of) the object for whichs::h()
is called.This is not allowed in a
const
member function becausethis
is a pointer toconst
; that is,*this
hasconst
type.