Access to non-public class members
21 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
Matt J
2024-2-11
编辑:Matt J
2024-2-11
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 个评论
更多回答(2 个)
Tijana Röhrer
2024-2-12
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
2024-2-9
编辑:Walter Roberson
2024-2-11
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 个评论
Walter Roberson
2024-2-12
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.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Programming Utilities 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!