Access to non-public class members
41 ビュー (過去 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!