How can I test private methods with DUnit?

后端 未结 7 649
温柔的废话
温柔的废话 2021-01-01 17:41

I have a class that I am unit testing into with DUnit. It has a number of methods some public methods and private methods.

type
  TAuth = class(TDataModule)
         


        
相关标签:
7条回答
  • 2021-01-01 18:08
    {$IFNDEF UNITEST}
    private
    {$ENDIF}
    

    Simple solution, which hardly is a hack. I frequently need to test private methods and this technique adds as little complication as possible.

    0 讨论(0)
  • 2021-01-01 18:09

    You don't need to make them public. Protected will do. Then you can subtype the class for unit testing and surface the protected methods. Example:

    type
      TAuth = class(TDataModule)
      protected
        procedure MethodIWantToUnitTest;
      public
        procedure PublicMethod;
      end;
    

    Now you can subtype it for your unit test:

    interface
    
    uses
      TestFramework, Classes, AuthDM;
    
    type
      // Test methods for class TAuthDM
      TestAuthDM = class(TTestCase)
         // stuff
      end;
    
      TAuthDMTester = class(TAuthDM)
      public
        procedure MethodIWantToUnitTestMadePublic;
      end;
    
    implementation
    
    procedure TAuthDMTester.MethodIWantToUnitTestMadePublic;
    begin
      MethodIWantToUnitTest;
    end;
    

    However, if the methods you want to unit test are doing things so intimately with the data module that it is not safe to have them anything but private, then you should really consider refactoring the methods in order to segregate the code which needs to be unit tested and the code which accesses the innards of the data module.

    0 讨论(0)
  • 2021-01-01 18:09

    I recommend the "XUnit Test Patterns" book by Gerard Meszaros:

    Test-Specific Subclass

    Question: How can we make code testable when we need to access private state of the SUT?

    Answer: Add methods that expose the state or behavior needed by the test to a subclass of the SUT.

    ... If the system under test (SUT) was not designed specifically to be testable, we may find that the test cannot get access to state that it must initialize or verify at some point in the test.

    The article also explains when to use it and which risks it carries.

    0 讨论(0)
  • 2021-01-01 18:11

    In general, when I get in this situation, I often realize that I'm violating the single responsibility principle. Of course I know nothing about your specific case, but MAYBE, that private methods should be in their own class. The TAuth would than have a reference to this new class in it's private section.

    0 讨论(0)
  • 2021-01-01 18:22

    Put the DUnit code within your unit. You can then access anything you like.

    0 讨论(0)
  • 2021-01-01 18:22

    With Extended RTTI (Delphi 2010 and newer), invoking private methods via RTTI is another option. This solution is also the top-rated answer in How do I test a class that has private methods, fields or inner classes?

    0 讨论(0)
提交回复
热议问题