Access to non-public class members
45 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Hello,
I'm currently writing unittests for a code-base which I'm not supposed to change (and honestly don't want to change). To say it nicely, its not written very testable. However I managed to test at least some parts of it. To increase the test coverage and to test things more defensively,
I would like to access non-public class members, such as private methods and properties.
As expected the following statement fails:
myInstance.privateMethod
% yields -> Cannot access method 'privateMethod' in class 'CustomersAwesomeClass'.
What I would like to see working is something like this:
% imaginary code, (similar to the invoke function for COM interfaces)
invoke(myInstance, "privateMethod", arg1 ...)
After spending a day trying various hacks, I'm about to give it up. Isn't it possible to achieve it somehow?
In other programming languages there are direct and indirect mechanisms like Reflection, Metaprogramming, Extensions methods, Friends, Function pointers, Runtime patching and others to achieve it. In MATLAB it seems none of these solution are doable and I don't understand why this is the case.
In my oppinion, access modifiers are supposed to prevent a wrong usage of an interface, but it should not prevent you from invoking code, because there might always be a usecase for that. This is also why there are many languages out there without access modifiers at all...
Anyway, if someone knows a workaround, then please share it with me! Other than that it would also be a solution to get a definitive answer that this is not doable, so that I stop wasting time on this. And if so, maybe Mathworks considers to introduce a backdoor here in the future then...
Any help is appreciated. Thanks
0 Commenti
Risposta accettata
Matt J
il 11 Feb 2024
Modificato: Matt J
il 11 Feb 2024
You could move the classdef to an @-folder, either manually or programmatically and either temporarily or permanently. Then, add invoke() as a method of the class in a separate mfile, so the folder looks like:
@CustomersAwesomeClass/CustomersAwesomeClass.m
@CustomersAwesomeClass/invoke.m
Now that invoke() has been made a method of the class, it will have access to private methods and properties. However, because this involves no editing of the classdef file CustomersAwesomeClass.m you can tell the customer that your test was non-invasive.
2 Commenti
Più risposte (2)
Tijana Röhrer
il 12 Feb 2024
Hi Tom,
one possibility to test private methods is to allow access to the testing framework. In the definition of the method, instead of setting it's access permissions to "private" directly, you would set them as
methods (Access = ?matlab.unittest.TestCase)
This sets the access to private, but additionally allows access to any subclass of matlab.unittest.TestCase, and therefore any test class. If you use other testing frameworks, you would have to use the appropriate superclass such as matlab.uitest.TestCase etc.
This would require a minor modification to your code, but it might be worthwhile.
Best,
Tijana
Walter Roberson
il 9 Feb 2024
Modificato: Walter Roberson
il 11 Feb 2024
In my oppinion, access modifiers are supposed to prevent a wrong usage of an interface, but it should not prevent you from invoking code, because there might always be a usecase for that.
External access to a non-public property is a "wrong usage of an interface" and MATLAB blocks that access.
It is an access contract: the class is written under the assumption that only the contracted operations can happen, and MATLAB enforces that indeed only the contracted operations can happen.
If there are backdoors possibilities then classes need to be written to protect against the backdoors, by using techniques such as checking the call stack to verify that the call is legitimate.
Consider a class that is acting like a bank account, with defined deposit and withdrawl methods. You do not want there to be a backdoor that permits you to withdraw without a trace.
I suspect that what you are looking for is something like the facility for mocking; https://www.mathworks.com/help/matlab/mocking-framework.html
5 Commenti
Walter Roberson
il 12 Feb 2024
And having a more liberal opinion about it, can still yield in highly secure software.
No, you cannot.
If you allow backdoors then you have to write the methods to protect against the possibility that this invocation used a backdoor.
Vedere anche
Categorie
Scopri di più su Testing Frameworks in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!