Open pedropapa opened 1 year ago
I was able to work around and create a PoC for implementing the outstanding functions: https://gist.github.com/pedropapa/b5d1726fac9a0972a57cadb0dce3afa4
I'm not familiar with low-level pawn code so my code looks junky, the most important is exposing an API so I can move on with my codebase.
Now I'm able to do something similar to what I proposed:
#include <y_testing_mocks>
#include <my_implementation>
#include <YSI_Core\y_testing>
@test(.group = "CreateAccount") ShouldSendMessageIfInvalid()
{
MockInit(); // Should be in BeforeAll ideally
MockReset("SendClientMessage");
ASSERT_EQ(CreateAccount(1, "ab"), 1);
ASSERT_TRUE(MOCK_CALL_COUNT("SendClientMessage", 1));
ASSERT_TRUE(MOCK_CALL("SendClientMessage", "1 0xFFFFFFFF Your name is invalid. Try another one"));
}
There still space for improvement:
MOCK_CALL_COUNT
and MOCK_CALL
to ASSERT_CALL_COUNT
and ASSERT_CALL
to make the assertion without wrapping it around ASSERT_TRUE
.MOCK_CALL
using a variadic function like this: MOCK_CALL("SendClientMessage", 1, 0xFFFFFFFF, "Your name is invalid. Try another one");
, tried to play around with getarg
with no luck.There was a vague skeleton for y_mock
a long time ago for exactly this, but it never got very far in implementation. You're right that it should be completed.
I've seen some discussion around the topic at #157, but couldn't find a way to do it with the current documentation for y_testing.
In unit testing you want to obviously test the unit, a single method (for instance), everything else within the file should not be tested (given they have their own tests or will be tested implicitly like private functions) and external calls should be mocked. I see in y_testing a good solution for integration tests, but it still lack important features in order to serve as a unit testing library.
Example:
The example shows the need to properly test my
CreateAccount
function. I need to mock the nativeGetPlayerName
to return a specific value during my test and spy onSendClientMessage
to check if it was called with the correct parameters.I reckon
MOCK_NATIVE_RETURN_VALUE
can be achieved using the y_hooks api, but forASSERT_CALL
orASSERT_CALL_COUNT
it would require some sort of async check with timers.I also took a read at open.mp's raknet mock solution, it facilitates integration tests by a margin, however it still isn't the solution for unit testing since for external calls we only need to check if the function was called with the correct parameters, we don't need to check if the external function is working properly (ideally the external function's implementation could even be mocked with dummy code).
I hope it makes sense 🙏