FabioBatSilva / ArduinoFake

Arduino mocking made easy
https://platformio.org/lib/show/1689/ArduinoFake
MIT License
102 stars 47 forks source link

Some issues when using String type #23

Open aliaksandr-panasiuk opened 3 years ago

aliaksandr-panasiuk commented 3 years ago

I've faced with a strange behavior when String type is used

a test contains the following

When(OverloadedMethod(ArduinoFake(Serial), println, size_t(const String &s))).AlwaysReturn();
String msg("test");
Serial.println(msg);
Verify(OverloadedMethod(ArduinoFake(Serial), println, size_t(const String &s)).Using("test")).Once();
// [FAILED]

it fails with a message ...'ArduinoFake(Serial).println(1)... "println(1)." <-- why '1' ?

BUT the following code works OK

When(OverloadedMethod(ArduinoFake(Serial), println, size_t(const char *))).AlwaysReturn();
Serial.println("test");
Verify(OverloadedMethod(ArduinoFake(Serial), println, size_t(const char *)).Using("test")).Once();
// [PASSED]

One more example which doesn't work

const char * msg = String("test").c_str();
Serial.println(msg);
Verify(OverloadedMethod(ArduinoFake(Serial), println, size_t(const char *)).Using("test")).Once();
// [FAILED]
// it prints 'ArduinoFake(Serial).println()' like println was called without any value at all

BUT this one works OK

const char * msg = "test";
Serial.println(msg);
Verify(OverloadedMethod(ArduinoFake(Serial), println, size_t(const char *)).Using("test")).Once();
// [PASSED]

[UPDATED] as I see, one of possible workaround for this is to modify the 'proxy' methods, and always create a copy of a String without calling free() method. E.g.

size_t Print::println(const String &s)
{
    return ArduinoFakeInstance(Print, this)->println(s);
}

replace to

size_t Print::println(const String &s)
{
    char * str = (char*)malloc(s.length() * sizeof(char));
    strcpy(str, s.c_str());
    // do not call free(str).
    return ArduinoFakeInstance(Print, this)->println(str);
}