Reputation: 1334
I want to start writing some unit tests for a buffer class and I`m struggling a bit with the static create method.
class MyBuffer
{
public:
static MyBuffer* create(int32 bufSize)
{
if(!bufSize)
return nullptr;
char* internalBuf = (char*)malloc(bufSize);
if(nullptr == internalBuf) return nullptr;
return new MyBuffer(internalBuf, bufSize);
}
public bool write(void* data, int32 dataSize) {...}
private:
MyBuffer(char* buf, int32 size) : internalBuf(buf), size(bufSize) {}
char* internalBuf = nullptr;
int32 bufSize = 0;
};
//just dummy code
TEST(MyBuffer bufferWithZeroSize)
{
auto buf = MyBuffer::create(0);
ASSERT_True(nullptr == buf);
}
TEST(MyBuffer writeDataToBuffer)
{
//arrange
auto buf = MyBuffer::create(50);
ASSERT_NotNull(buf); //is this call needed
//act
buf->write(...);
//assert
}
Verifying the MyBuffer creation process seems to be ok.
In my 2nd test, is it ok to assume that the creation process of the MyBuffer was successfull? Otherwise I have to check it in the "act" part of the unit test. This sounds not so reasonable to me because I want to check only one thing per unit test. On the other side, I know the malloc call can fail.
How do you test objects with a static create method? Are there any useful test strategies or is it recommend to refactor such objects? I mainly use the static create methods in order to avoid that the caller of the object forget to initialize the object correctly. Therefore it sounds to me a valid approach.
Upvotes: 0
Views: 64
Reputation: 13134
I mainly use the static create methods in order to avoid that the caller of the object forget to initialize the object correctly.
There is no way the user could possiby "forget" to initialize an instance of the MyBuffer
shown below.
#include <cstddef>
class MyBuffer
{
private:
std::size_t bufSize;
char* internalBuf;
public:
MyBuffer(std::size_t size)
: bufSize{ size }
internalBuf{ new char[size] },
{}
// + whats missing to satisfy the rule of 5
bool write(char *data, std::size_t dataSize)
{
/* ... */
return true;
}
};
Notice: Don't use malloc()
for no appearant reason. Use std::size_t
for the size of objects in memory.
#include <cstddef>
#include <stdexcept>
#include <algorithm>
class MyBuffer
{
public:
static constexpr std::size_t min_size{ 10 };
static constexpr std::size_t max_size{ 42 };
private:
std::size_t bufSize;
char* internalBuf;
public:
MyBuffer(std::size_t size)
: bufSize{ size == std::clamp(size, min_size, max_size) ?
size : throw std::invalid_argument{ "size is out of range!" } },
internalBuf{ new char[bufSize] }
{}
};
Upvotes: 1
Reputation: 11000
I suspect you don't need to write a buffer class in the first place and that std::vector<char>
can be used instead. In general you should try to steer away from raw memory management (don't write new/delete/malloc/free at all (especially the delete/free)).
As for the unit testing question, yes, it is fine to some setup in order to arrive at your actual test(or tests). When you reuse setup across tests its often called a Fixture. I think it is not uncommon to test several things within the same test. Sometimes performance of the tests themselves can also be a thing, and then it makes sense to test more things if the setup is costly.
Upvotes: 0