Files
arcs/arcs-sdk/modules/cpputest/tests/CppUTestExt/MockFailureTest.cpp
2026-08-13 16:50:52 +08:00

322 lines
15 KiB
C++

/*
* Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockFailure.h"
#include "CppUTestExt/MockCheckedExpectedCall.h"
#include "CppUTestExt/MockExpectedCallsList.h"
#include "MockFailureReporterForTest.h"
TEST_GROUP(MockFailureTest)
{
MockFailureReporter reporter;
MockExpectedCallsList *list;
MockCheckedExpectedCall* call1;
MockCheckedExpectedCall* call2;
MockCheckedExpectedCall* call3;
MockCheckedExpectedCall* call4;
MockCheckedExpectedCall* call5;
void setup () CPPUTEST_OVERRIDE
{
list = new MockExpectedCallsList;
call1 = new MockCheckedExpectedCall;
call2 = new MockCheckedExpectedCall;
call3 = new MockCheckedExpectedCall;
call4 = new MockCheckedExpectedCall;
call5 = new MockCheckedExpectedCall;
}
void teardown () CPPUTEST_OVERRIDE
{
delete list;
delete call1;
delete call2;
delete call3;
delete call4;
delete call5;
CHECK_NO_MOCK_FAILURE();
MockFailureReporterForTest::clearReporter();
}
void addThreeCallsToList()
{
list->addExpectedCall(call1);
list->addExpectedCall(call2);
list->addExpectedCall(call3);
}
void addFiveCallsToList()
{
list->addExpectedCall(call1);
list->addExpectedCall(call2);
list->addExpectedCall(call3);
list->addExpectedCall(call4);
list->addExpectedCall(call5);
}
void checkUnexpectedNthCallMessage(unsigned int count, const char* expectedOrdinal)
{
MockExpectedCallsList callList;
MockCheckedExpectedCall expectedCallSingle(1);
MockCheckedExpectedCall expectedCallMulti(count-1);
expectedCallSingle.withName("bar");
expectedCallMulti.withName("bar");
if (count > 1) {
callList.addExpectedCall(&expectedCallSingle);
expectedCallSingle.callWasMade(1);
}
if (count > 2) {
callList.addExpectedCall(&expectedCallMulti);
for (unsigned int i = 1; i < (count - 1); i++) {
expectedCallMulti.callWasMade(i+1);
}
}
MockUnexpectedCallHappenedFailure failure(UtestShell::getCurrent(), "bar", callList);
SimpleString expectedMessage = StringFromFormat("Mock Failure: Unexpected additional (%s) call to function: bar\n\tEXPECTED", expectedOrdinal);
STRCMP_CONTAINS(expectedMessage.asCharString(), failure.getMessage().asCharString());
}
};
TEST(MockFailureTest, noErrorFailureSomethingGoneWrong)
{
MockFailure failure(UtestShell::getCurrent());
STRCMP_EQUAL("Test failed with MockFailure without an error! Something went seriously wrong.", failure.getMessage().asCharString());
}
TEST(MockFailureTest, unexpectedCallHappened)
{
MockUnexpectedCallHappenedFailure failure(UtestShell::getCurrent(), "foobar", *list);
STRCMP_EQUAL("Mock Failure: Unexpected call to function: foobar\n"
"\tEXPECTED calls that WERE NOT fulfilled:\n"
"\t\t<none>\n"
"\tEXPECTED calls that WERE fulfilled:\n"
"\t\t<none>", failure.getMessage().asCharString());
}
TEST(MockFailureTest, expectedCallDidNotHappen)
{
call1->withName("foobar");
call2->withName("world").withParameter("boo", 2).withParameter("hello", "world");
call3->withName("haphaphap");
call3->callWasMade(1);
addThreeCallsToList();
MockExpectedCallsDidntHappenFailure failure(UtestShell::getCurrent(), *list);
STRCMP_EQUAL("Mock Failure: Expected call WAS NOT fulfilled.\n"
"\tEXPECTED calls that WERE NOT fulfilled:\n"
"\t\tfoobar -> no parameters (expected 1 call, called 0 times)\n"
"\t\tworld -> int boo: <2 (0x2)>, const char* hello: <world> (expected 1 call, called 0 times)\n"
"\tEXPECTED calls that WERE fulfilled:\n"
"\t\thaphaphap -> no parameters (expected 1 call, called 1 time)", failure.getMessage().asCharString());
}
TEST(MockFailureTest, MockUnexpectedNthAdditionalCallFailure)
{
checkUnexpectedNthCallMessage(2, "2nd");
checkUnexpectedNthCallMessage(3, "3rd");
checkUnexpectedNthCallMessage(4, "4th");
checkUnexpectedNthCallMessage(11, "11th");
checkUnexpectedNthCallMessage(12, "12th");
checkUnexpectedNthCallMessage(13, "13th");
checkUnexpectedNthCallMessage(14, "14th");
checkUnexpectedNthCallMessage(21, "21st");
checkUnexpectedNthCallMessage(22, "22nd");
checkUnexpectedNthCallMessage(23, "23rd");
}
TEST(MockFailureTest, MockUnexpectedInputParameterFailure)
{
call1->withName("foo").withParameter("boo", 2);
call2->withName("foo").withParameter("boo", 3.3);
call3->withName("unrelated");
addThreeCallsToList();
MockNamedValue actualParameter("bar");
actualParameter.setValue(2);
MockUnexpectedInputParameterFailure failure(UtestShell::getCurrent(), "foo", actualParameter, *list);
STRCMP_EQUAL("Mock Failure: Unexpected parameter name to function \"foo\": bar\n"
"\tEXPECTED calls that WERE NOT fulfilled related to function: foo\n"
"\t\tfoo -> int boo: <2 (0x2)> (expected 1 call, called 0 times)\n"
"\t\tfoo -> double boo: <3.3> (expected 1 call, called 0 times)\n"
"\tEXPECTED calls that WERE fulfilled related to function: foo\n"
"\t\t<none>\n"
"\tACTUAL unexpected parameter passed to function: foo\n"
"\t\tint bar: <2 (0x2)>", failure.getMessage().asCharString());
}
TEST(MockFailureTest, MockUnexpectedOutputParameterFailure)
{
int out1;
int out2;
call1->withName("foo").withOutputParameterReturning("boo", &out1, sizeof(out1));
call2->withName("foo").withOutputParameterReturning("boo", &out2, sizeof(out2));
call3->withName("unrelated");
addThreeCallsToList();
MockNamedValue actualParameter("bar");
actualParameter.setValue((void *)0x123);
MockUnexpectedOutputParameterFailure failure(UtestShell::getCurrent(), "foo", actualParameter, *list);
STRCMP_EQUAL("Mock Failure: Unexpected output parameter name to function \"foo\": bar\n"
"\tEXPECTED calls that WERE NOT fulfilled related to function: foo\n"
"\t\tfoo -> const void* boo: <output> (expected 1 call, called 0 times)\n"
"\t\tfoo -> const void* boo: <output> (expected 1 call, called 0 times)\n"
"\tEXPECTED calls that WERE fulfilled related to function: foo\n"
"\t\t<none>\n"
"\tACTUAL unexpected output parameter passed to function: foo\n"
"\t\tvoid* bar", failure.getMessage().asCharString());
}
TEST(MockFailureTest, MockUnexpectedUnmodifiedOutputParameterFailure)
{
int out1;
call1->withName("foo").withOutputParameterReturning("boo", &out1, sizeof(out1));
call2->withName("foo").withUnmodifiedOutputParameter("boo");
call3->withName("unrelated");
addThreeCallsToList();
MockNamedValue actualParameter("bar");
actualParameter.setValue((void *)0x123);
MockUnexpectedOutputParameterFailure failure(UtestShell::getCurrent(), "foo", actualParameter, *list);
STRCMP_EQUAL("Mock Failure: Unexpected output parameter name to function \"foo\": bar\n"
"\tEXPECTED calls that WERE NOT fulfilled related to function: foo\n"
"\t\tfoo -> const void* boo: <output> (expected 1 call, called 0 times)\n"
"\t\tfoo -> const void* boo: <output> (expected 1 call, called 0 times)\n"
"\tEXPECTED calls that WERE fulfilled related to function: foo\n"
"\t\t<none>\n"
"\tACTUAL unexpected output parameter passed to function: foo\n"
"\t\tvoid* bar", failure.getMessage().asCharString());
}
TEST(MockFailureTest, MockUnexpectedParameterValueFailure)
{
call1->withName("foo").withParameter("boo", 2);
call2->withName("foo").withParameter("boo", 10);
call3->withName("unrelated");
addThreeCallsToList();
MockNamedValue actualParameter("boo");
actualParameter.setValue(20);
MockUnexpectedInputParameterFailure failure(UtestShell::getCurrent(), "foo", actualParameter, *list);
STRCMP_EQUAL("Mock Failure: Unexpected parameter value to parameter \"boo\" to function \"foo\": <20 (0x14)>\n"
"\tEXPECTED calls that WERE NOT fulfilled related to function: foo\n"
"\t\tfoo -> int boo: <2 (0x2)> (expected 1 call, called 0 times)\n"
"\t\tfoo -> int boo: <10 (0xa)> (expected 1 call, called 0 times)\n"
"\tEXPECTED calls that WERE fulfilled related to function: foo\n"
"\t\t<none>\n"
"\tACTUAL unexpected parameter passed to function: foo\n"
"\t\tint boo: <20 (0x14)>", failure.getMessage().asCharString());
}
TEST(MockFailureTest, MockExpectedParameterDidntHappenFailure)
{
call1->withName("foo").withParameter("bar", 2).withParameter("boo", "str");
call1->inputParameterWasPassed("bar");
call2->withName("foo").withParameter("bar", 10).withParameter("boo", "bleh");
call2->callWasMade(1);
call2->inputParameterWasPassed("bar");
call2->inputParameterWasPassed("boo");
call3->withName("foo").withParameter("bar", 2).withParameter("boo", "blah").withParameter("baa", 0u);
call3->inputParameterWasPassed("bar");
call4->withName("foo").withParameter("bar", 20);
call5->withName("unrelated");
addFiveCallsToList();
MockExpectedCallsList matchingCalls;
matchingCalls.addExpectedCall(call1);
matchingCalls.addExpectedCall(call3);
MockExpectedParameterDidntHappenFailure failure(UtestShell::getCurrent(), "foo", *list, matchingCalls);
STRCMP_EQUAL("Mock Failure: Expected parameter for function \"foo\" did not happen.\n"
"\tEXPECTED calls with MISSING parameters related to function: foo\n"
"\t\tfoo -> int bar: <2 (0x2)>, const char* boo: <str> (expected 1 call, called 0 times)\n"
"\t\t\tMISSING parameters: const char* boo\n"
"\t\tfoo -> int bar: <2 (0x2)>, const char* boo: <blah>, unsigned int baa: <0 (0x0)> (expected 1 call, called 0 times)\n"
"\t\t\tMISSING parameters: const char* boo, unsigned int baa\n"
"\tEXPECTED calls that WERE NOT fulfilled related to function: foo\n"
"\t\tfoo -> int bar: <2 (0x2)>, const char* boo: <str> (expected 1 call, called 0 times)\n"
"\t\tfoo -> int bar: <2 (0x2)>, const char* boo: <blah>, unsigned int baa: <0 (0x0)> (expected 1 call, called 0 times)\n"
"\t\tfoo -> int bar: <20 (0x14)> (expected 1 call, called 0 times)\n"
"\tEXPECTED calls that WERE fulfilled related to function: foo\n"
"\t\tfoo -> int bar: <10 (0xa)>, const char* boo: <bleh> (expected 1 call, called 1 time)",
failure.getMessage().asCharString());
}
TEST(MockFailureTest, MockNoWayToCompareCustomTypeFailure)
{
MockNoWayToCompareCustomTypeFailure failure(UtestShell::getCurrent(), "myType");
STRCMP_EQUAL("MockFailure: No way to compare type <myType>. Please install a MockNamedValueComparator.", failure.getMessage().asCharString());
}
TEST(MockFailureTest, MockUnexpectedObjectFailure)
{
call1->withName("foo").onObject((void*) 0x02);
call2->withName("foo").onObject((void*) 0x03);
call2->callWasMade(1);
call2->wasPassedToObject();
call3->withName("unrelated");
addThreeCallsToList();
MockUnexpectedObjectFailure failure(UtestShell::getCurrent(), "foo", (void*)0x1, *list);
STRCMP_EQUAL(StringFromFormat (
"MockFailure: Function called on an unexpected object: foo\n"
"\tActual object for call has address: <%p>\n"
"\tEXPECTED calls that WERE NOT fulfilled related to function: foo\n"
"\t\t(object address: %p)::foo -> no parameters (expected 1 call, called 0 times)\n"
"\tEXPECTED calls that WERE fulfilled related to function: foo\n"
"\t\t(object address: %p)::foo -> no parameters (expected 1 call, called 1 time)",
(void*) 0x01, (void*) 0x02, (void*) 0x03).asCharString(), failure.getMessage().asCharString());
}
TEST(MockFailureTest, MockExpectedObjectDidntHappenFailure)
{
call1->withName("foo").onObject((void*) 0x02);
call2->withName("foo").onObject((void*) 0x03);
call2->callWasMade(1);
call2->wasPassedToObject();
call3->withName("unrelated");
addThreeCallsToList();
MockExpectedObjectDidntHappenFailure failure(UtestShell::getCurrent(), "foo", *list);
STRCMP_EQUAL(StringFromFormat(
"Mock Failure: Expected call on object for function \"foo\" but it did not happen.\n"
"\tEXPECTED calls that WERE NOT fulfilled related to function: foo\n"
"\t\t(object address: %p)::foo -> no parameters (expected 1 call, called 0 times)\n"
"\tEXPECTED calls that WERE fulfilled related to function: foo\n"
"\t\t(object address: %p)::foo -> no parameters (expected 1 call, called 1 time)",
(void*) 0x2, (void*) 0x3).asCharString(), failure.getMessage().asCharString());
}