Cha*_*iga 17 delphi unit-testing dunit
我有一个班级,我正在与DUnit进行单元测试.它有一些方法,一些公共方法和私有方法.
type
TAuth = class(TDataModule)
private
procedure PrivateMethod;
public
procedure PublicMethod;
end;
Run Code Online (Sandbox Code Playgroud)
为了为这个类编写单元测试,我必须公开所有的方法.
是否有一种不同的方式来声明私有方法,以便我仍然可以测试它们,但它们不公开?
Cra*_*ntz 21
你不需要公开它们.受保护的人会这样做.然后,您可以对类进行子类型以进行单元测试并显示受保护的方法.例:
type
TAuth = class(TDataModule)
protected
procedure MethodIWantToUnitTest;
public
procedure PublicMethod;
end;
Run Code Online (Sandbox Code Playgroud)
现在您可以为您的单元测试进行子类型化:
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;
Run Code Online (Sandbox Code Playgroud)
但是,如果你想要进行单元测试的方法与数据模块密切相关,除了私有之外它们是不安全的,那么你应该考虑重构方法以便分离需要单元的代码.测试和访问数据模块内部的代码.
这有点hacky,但我喜欢使用这个条件编译指令:
{$IfNDef TEST}
private
{$EndIf}
Run Code Online (Sandbox Code Playgroud)
您的单元测试项目应该定义TEST project ? conditional defines.
如果没有可见性规范,它们就会发布.注意:如果私有可见性不是类声明中的第一个,它将获得先前的定义.一种更安全的方式,但更冗长,更不清楚,将是:
private
{$IfDef TEST}
public
{$EndIf}
Run Code Online (Sandbox Code Playgroud)
这比子类或其他方法有一些优点:
我认为这是一个更清晰的解决方案,并且比选择的答案更好.
当我使用它时,我还配置测试项目以将构建对象放在主项目的不同目录中.这可以防止带有TEST指令的二进制文件与其他代码混合.
我推荐Gerard Meszaros 的" XUnit Test Patterns "一书:
问题:当我们需要访问SUT的私有状态时,我们如何才能使代码可测试?
答案:添加将测试所需的状态或行为暴露给SUT的子类的方法.
...如果被测系统(SUT)并非专门设计为可测试的,我们可能会发现测试无法访问状态,表明它必须在测试的某个时刻进行初始化或验证.
该文章还解释了何时使用它以及它带来的风险.