matlab - 使用 matlab 测试框架对异常执行单元测试时出错
问题描述
我在文件夹中有以下课程+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
那么为什么我无法在测试用例中正确捕获异常呢?如何正确检查是否抛出异常以便通过测试?
解决方案
You need to pass a function handle to verifyError. What is happening now is you are calling this.verifyError(options.setHostname(hostName), 'WTrade:invalidParameter');
which is actually invoking options.setHostname(hostName)
with one output argument to pass as an argument to verifyError. Instead it should be:
this.verifyError(@() options.setHostname(hostName), 'WTrade:invalidParameter');
Also, I would recommend using a standard property Hostname
and instead of writing a setter method use the validation syntax, like so:
classdef PostgreSQLConnectionOptions < handle
properties
Hostname(1,1) string = "";
end
end
Not, if you need to do more custom validation you can always write a setter method like so:
methods
function set.Hostname(options, hostname)
% some additional validation here
end
end
Note though when you use the properties, in order to use verifyError you'll need to wrap it in a function:
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
Even though you need to wrap this in a function for testing, it is by and large a better experience to use properties as they are. We have built in encapsulation with matlab, and I think it's best to leverage it.
推荐阅读
- rust - 使用 flat_map 替换字符串中的值
- amazon-web-services - 当您的 s3 存储桶达到特定帐户最大限制的 90% 时发出警报或监控
- python - 在字典列表中查找特定键的平均值
- python-3.x - 使用 tkinter.Tk() 类执行代码时遇到问题
- javascript - 使用 PHP 的 Bootstrap 模式在 jQuery Full Calendar 中添加事件
- python - 从 Python 中另一个类中的另一个函数调用一个类中的一个函数内的函数
- python - 在数据框中查找列值
- sql - Oracle 流水线表函数并将结果插入到 Oracle 表中
- elasticsearch - 当 CPU 使用率很高但有未使用的 CPU 积分时该怎么办?
- c++ - 如何用单词排列向量中的每个字符?