CPPUTest Mock getting data pointer data for testing? - c++

I have a mock for a c function
int Eeprom_WriteBuffer(uint32_t address, uint8_t *data, uint16_t data_len)
{
return mock("eeprom").actualCall("Eeprom_WriteBuffer")
.withParameter("address", address)
.withParameter("data", data)
.withParameter("data_len", data_len)
.withOutputParameter("data", data)
.returnIntValueOrDefault(-1);
}
The function is that I provide it some byte array and it writes this to eeprom.
I want to be able to test that the data my man in the middle function passed down to the mock is what I expect.
eg
TEST (TestGroup, Test)
{
uint8_t data[424];
for (unsigned char & i : data)
i = rand() % UINT8_MAX;
uint8_t actual_data[sizeof(data)];
mock("eeprom").expectOneCall("Eepriom_WriteBuffer")
.withParameter("address", 0)
.<GET THE DATA OUT TO TEST>("data", actual_data, sizeof(actual_data))
.andReturnValue(sizeof(data));
ManInTheMiddle(data, sizeof(data));
MEMCMP_EQUAL(data, actual_data, sizeof(data));
}
Is this possible with this framework or am I going to have to create some buffers to be able to pull the actual data from?

Related

Deserialize Json object from mqtt payload using ArduinoJson library

I'm trying to deserialize a Json object using the ArduinoJson 6 library. The object is passing through a mqtt callback using the PubSubClient library. The payload contains the following example: "{\"action\":\"message\",\"amount\":503}" but I am unable to retrieve the amount value. Only zeros are returned when using the following:
void messageReceived(char *topic, byte *payload, unsigned int length)
{
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload, length);
const int results = doc["amount"];
Serial.print(results);
}
This works and returns 503 as needed:
DynamicJsonDocument doc(1024);
char json[] = "{\"action\":\"message\",\"amount\":503}";
deserializeJson(doc, json);
const int results = doc["amount"];
Serial.print(results);
I see the results of the payload when I use the following method:
void messageReceived(char *topic, byte *payload, unsigned int length)
{
for (unsigned int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
}
What is preventing me from being able to parse out the amount value from the first method?
When programming in C++, it always need to be aware the type of data that you are dealing with. The payload is a byte array, which is not what deserializeJson(doc, payload, length); is expecting, see the function signature of deserializeJson().
void messageReceived(char *topic, byte *payload, unsigned int length)
{
DynamicJsonDocument doc(128);
deserializeJson(doc, (char*) payload, length);
Serial.print(doc["amount"]);
}
Update & resolution:
The first method in my original post worked fine once I fixed the data that was being sent from the Lambda function to the IOT side. (Something I didn't include in my original question and didn't think it was relevant. Turns out it was.) Here is a snippet from the Lambda function that is receiving the data. The issue was that the data was being sent as a string and not parsed. Once I stringified the response and then parsed the output, it worked. Thank you #hcheung for the assistance and helpful info. Your suggestion works as well but only after I fixed the Lambda function.
async function sendToIOT(response) {
const data = JSON.stringify(response);
const iotResponseParams = {
topic: 'mythingname/subscribe',
payload: JSON.parse(data)
};
return iotdata.publish(iotResponseParams).promise()
}

Creating an Array C++

I have two int values:
v_y
v_x
That I would like to convert to a size 2 char array then write to my serial port.
I currently have this code that isn't working:
void Array2 (char charArray[], int sizeOfArray);
........
}
{
char one[] = { 'v_x', 'v_y' };
Array2(one, 2);
Serial::WriteData(one, 2);
}
}
I currently get two errors:
a nonstatic member reference must be relative to a specific object
and
'Serial::WriteData':illegal call of non-static member function.
Any help, hint or idea on what I'm doing wrong would be great!
Edit: I'm using this code to communicate with my serialport CODE
// data.h or similar, you need this for both the arduino and desktop machine
struct Data {
double v_x;
double v_y;
}
On your arduino: To write
Data data = {
.v_x = 1.0, // Example put your values here
.v_y = 2.0,
};
// This should write from your Arduino to the computer
Serial::WriteData((const char*)data, sizeof(data));
On your computer
Data data;
// This reads from the serial port, and put the data in the struct
auto len = SP->ReadData((const char*)data, sizeof(data));
// check that data is the right size
// use the data from data.v_x and data.v_y
auto v_x = data.v_x;
auto v_y = data.v_y; // etc

How to convert int to byte in unit testing DataRow?

I started making tests where i check bytes but i noticed that I can't write byte in DataRow, because I get a message: System.ArgumentException: Object of type 'System.Int32' cannot be converted to type 'System.Byte'.
How can I convert int to byte in DataRow?
[DataRow(12, 12)]
[DataRow(23, 23)]
public void Consturcot_1param(byte h, byte expectedH)
{
Time t = new Time(h);
AssertTime(t, expectedH, expectedM: 0, expectedS: 0);
}
The simplest solution would be to cast int to byte:
[DataRow((byte)12, (byte)12)]
[DataRow((byte)23, (byte)23)]
public void TestMethod(byte h, byte expectedH)
{ }

Cast an unsigned short/int to char *

I have a function like this
void UnitTestWorker::constructTestPayload(QByteArray &payload)
{
QString List = "127.0.0.1";
unsigned short Port = 12344;
unsigned int RequestId = 1;
memcpy(payload.data(),reinterpret_cast<char*>Port,sizeof(Port));
memcpy(payload.data()+sizeof(Port),reinterpret_cast<char*>RequestId ,sizeof(RequestId ));
}
But I am getting access violation error, it seems like I can't do something like reinterpret_cast<char*>Port or reinterpret_cast<char*>RequestId.
You have to ensure that QByteArray &payload has a sufficient size to receive the data you byte copy to it:
if (payload.size()<sizeof(Port)+sizeof(RequestId))
throw exception ("Ouch !! payload too small");
memcpy(payload.data(),reinterpret_cast<char*>(&Port),sizeof(Port));
memcpy(payload.data()+sizeof(Port),reinterpret_cast<char*>(&RequestId) ,sizeof(RequestId ));

Testing implementation over interface

I'm starting with test coverage for my C++ project and it was oddness for me, that a lot of frameworks cannot create parametrized unit test.
For example I have interface:
class IBuffer {
public:
virtual void pushBytes(void *data, int length) = 0;
virtual int getSize() = 0;
};
And a few implementors :
class BufferImplOne{};
class BufferImplTwo{};
Now I want to check that pushing bytes to buffer will really increment its size:
TEST_CASE("example/test", "Test for any IBuffer implementor") {
IBuffer *buf = // ... {I want external parameter to be here}
REQUIRE( buf->getSize() == 0 );
int dataLength = 10;
int data[dataLength];
buf->pushBytes(data, dataLength * sizeof(int));
REQUIRE( buf->getSize() == dataLength * sizeof(int));
}
Now I'm gonna to test each implementation, and first thing I want to do - is to check if implementor meets interface tests. But I don't want to copypaste the same code twice, I just want to pass implementation as a parameter to interface test. How to deal with such problem?
I am using CATCH, but seems like other framework don't provide same functionality too.
Anyway I am newcomer in unit testing and maybe I misunderstood something basic?
Something like this:
void TestBuffer(IBuffer& buf)
{
REQUIRE( buf.getSize() == 0 );
int dataLength = 10;
int data[dataLength];
buf.pushBytes(data, dataLength * sizeof(int));
REQUIRE( buf.getSize() == dataLength * sizeof(int));
}
TEST_CASE("example/test", "Test for BufferImplOne implementor")
{
BufferImplOne one;
TestBuffer(one);
}
TEST_CASE("example/test", "Test for BufferImplTwo implementor")
{
BufferImplTwo two;
TestBuffer(two);
}
Well, it's bona fide polymorphism.
void test(IBuffer& ib) {
// ... your tests here ...
}
int main() {
BufferImplOne one;
test(one);
BufferImplTwo two;
test(two);
}
I don't quite see what a framework could provide...