我在文件夹+WTrade/+Database/@PostgreSQLConnectionOptions
中有以下课程:
classdef PostgreSQLConnectionOptions < handle
properties (Access = private)
databaseHost
end
methods (Access = public)
function this = PostgreSQLConnectionOptions()
this.databaseHost = "";
end
function setHostname(this, name)
if ~isstring(name)
me = MException("WTrade:invalidParameter", "WTrade.Database.PostgreSQLConnectionOption.setHostname: name must be a string");
throw(me);
end
if 1 ~= length(name)
me = MException("WTrade:invalidParameter", "WTrade.Database.PostgreSQLConnectionOption.setHostname: name array size must be 1");
throw(me);
end
this.databaseHost = name;
end
end
end
我想对此课程进行单元测试。我有以下测试课
classdef PostgreSQLConnectionOptionsTest < matlab.unittest.TestCase
methods (Test)
function testWrongHostnameArray(this)
options = WTrade.Database.PostgreSQLConnectionOptions();
hostName = ["h1" "h2"];
this.verifyError(options.setHostname(hostName), 'WTrade:invalidParameter');
end
end
end
当我尝试使用以下脚本运行测试时:
import matlab.unittest.TestSuite
import matlab.unittest.constraints.Throws;
databaseSuite = TestSuite.fromFolder("tests/WTrade/Database");
result = run(databaseSuite);
我收到以下错误:
>> runtests('PostgreSQLConnectionOptionsTest','ProcedureName','testWrongHostnameArray')
Running PostgreSQLConnectionOptionsTest
32 options = WTrade.Database.PostgreSQLConnectionOptions();
================================================================================
Error occurred in PostgreSQLConnectionOptionsTest/testWrongHostnameArray and it did not run to completion.
---------
Error ID:
---------
'MATLAB:TooManyOutputs'
--------------
Error Details:
--------------
Error using WTrade.Database.PostgreSQLConnectionOptions/setHostname
Too many output arguments.
Error in PostgreSQLConnectionOptionsTest/testWrongHostnameArray (line 34)
this.verifyError(options.setHostname(hostName), 'WTrade:invalidParameter');
================================================================================
.
Done PostgreSQLConnectionOptionsTest
__________
Failure Summary:
Name Failed Incomplete Reason(s)
=======================================================================================
PostgreSQLConnectionOptionsTest/testWrongHostnameArray X X Errored.
ans =
TestResult with properties:
Name: 'PostgreSQLConnectionOptionsTest/testWrongHostnameArray'
Passed: 0
Failed: 1
Incomplete: 1
Duration: 2.0606
Details: [1×1 struct]
Totals:
0 Passed, 1 Failed (rerun), 1 Incomplete.
2.0606 seconds testing time.
我不了解'MATLAB:TooManyOutputs'
错误。我已经在matlab中直接尝试了该方法,并且效果符合预期;我测试该参数是否为字符串,如果不是,它将引发异常。
当我运行以下命令时:
a = WTrade.Database.PostgreSQLConnectionOptions
a.setHostname(["p1", "p2")
我得到了我所期望的错误。
Error using WTrade.Database.PostgreSQLConnectionOptions/setHostname (line 43)
WTrade.Database.PostgreSQLConnectionOption.setHostname: name array size must be 1
那么,为什么我不能在测试用例中正确捕获异常?如何正确检查是否抛出了异常,以便可以通过测试?
答案 0 :(得分:1)
您需要传递一个函数句柄来验证错误。现在发生的事情是您正在调用this.verifyError(options.setHostname(hostName), 'WTrade:invalidParameter');
,它实际上是通过一个输出参数调用options.setHostname(hostName)
并将其作为参数传递给verifyError。相反,它应该是:
this.verifyError(@() options.setHostname(hostName), 'WTrade:invalidParameter');
此外,我建议使用标准属性Hostname
,而不是使用验证语法来编写setter方法,如下所示:
classdef PostgreSQLConnectionOptions < handle
properties
Hostname(1,1) string = "";
end
end
不是,如果您需要执行更多自定义验证,则可以始终像这样编写setter方法:
methods
function set.Hostname(options, hostname)
% some additional validation here
end
end
请注意,尽管在使用属性时,要使用verifyError,您需要将其包装在函数中:
classdef PostgreSQLConnectionOptionsTest < matlab.unittest.TestCase
methods (Test)
function testWrongHostnameArray(this)
options = WTrade.Database.PostgreSQLConnectionOptions();
hostName = ["h1" "h2"];
this.verifyError(@setHostname, 'WTrade:invalidParameter');
function setHostname
options.Hostname = hostname;
end
end
end
end
即使您需要将此属性包装在测试函数中,但按原样使用属性通常还是更好的体验。我们有built in encapsulation with matlab,我认为最好利用它。