- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用新的 unit testing framework对于在 R2013a 中引入的 MATLAB,matlab.unittest。我想写一个断言,以下两种情况都会发生:
我找到了 verifyError
方法,但这似乎只允许我检查标识符或错误元类。
另一个选项似乎是 verifyThat
与 Throws
约束。这似乎更有希望,但 Throws
的文档似乎有些稀疏,我不知道如何让它做我想做的事。
我意识到我可以将消息文本添加到错误标识符中,但我真的不想这样做。消息文本来自使用 mex 文件调用的 native 库。文本用空格等格式化。文本可能会很长,并且会弄乱错误标识符。
那么,是否有可能实现我想要的,如果可以,如何实现?
最佳答案
没有现成的功能可以做到这一点。这是破解它的一种方法。
考虑我们正在测试的以下功能。它在非数字输入上抛出特定错误:
function out = increment(x)
if ~isa(x,'numeric')
error('increment:NonNumeric', 'Input must be numeric.');
end
out = x + 1;
end
这是单元测试代码:
classdef IncrementTest < matlab.unittest.TestCase
methods (Test)
function testOutput(t)
t.verifyEqual(increment(1), 2);
end
function testClass(t)
t.verifyClass(increment(1), class(2));
end
function testErrId(t)
t.verifyError(@()increment('1'), 'increment:NonNumeric');
end
function testErrIdMsg(t)
% expected exception
expectedME = MException('increment:NonNumeric', ...
'Input must be numeric.');
noErr = false;
try
[~] = increment('1');
noErr = true;
catch actualME
% verify correct exception was thrown
t.verifyEqual(actualME.identifier, expectedME.identifier, ...
'The function threw an exception with the wrong identifier.');
t.verifyEqual(actualME.message, expectedME.message, ...
'The function threw an exception with the wrong message.');
end
% verify an exception was thrown
t.verifyFalse(noErr, 'The function did not throw any exception.');
end
end
end
try/catch block 的使用受到旧 xUnit Test Framework 中的 assertExceptionThrown
函数的启发。由史蒂夫埃丁斯。(更新:该框架似乎已从文件交换中删除,我想鼓励改用新的内置框架。如果您感兴趣,这里是旧 xUnit 的一个流行分支: psexton/matlab-xunit ).
如果您想更灵活地测试错误消息,请使用 verifyMatches
而是使用正则表达式匹配字符串。
此外,如果您喜欢冒险,可以研究 matlab.unittest.constraints.Throws
类并创建你的 own version除错误 ID 外,它还检查错误消息。
ME = MException('error:id', 'message');
import matlab.unittest.constraints.Throws
%t.verifyThat(@myfcn, Throws(ME));
t.verifyThat(@myfcn, ThrowsWithId(ME));
ThrowsWithId
是你的扩展版本
好的,我查看了 matlab.unittest.constraints.Throws
的代码我实现了一个 custom Constraint
类。
类类似于Throws
.它需要一个 MException
实例作为输入,并检查被测试的函数句柄是否抛出类似的异常(检查错误 ID 和消息)。它可以与任何断言方法一起使用:
testCase.assertThat(@fcn, ThrowsErr(ME))
testCase.assumeThat(@fcn, ThrowsErr(ME))
testCase.fatalAssertThat(@fcn, ThrowsErr(ME))
testCase.verifyThat(@fcn, ThrowsErr(ME))
从抽象类创建子类matlab.unittest.constraints.Constraint
,我们必须实现接口(interface)的两个功能:satisfiedBy
和 getDiagnosticFor
.另请注意,我们改为继承自另一个抽象类 FunctionHandleConstraint
,因为它提供了一些辅助方法来处理函数句柄。
构造函数采用预期的异常(作为 MException
实例)和一个可选输入,指定用于调用正在测试的函数句柄的输出参数的数量。
代码:
classdef ThrowsErr < matlab.unittest.internal.constraints.FunctionHandleConstraint
%THROWSERR Constraint specifying a function handle that throws an MException
%
% See also: matlab.unittest.constraints.Throws
properties (SetAccess = private)
ExpectedException;
FcnNargout;
end
properties (Access = private)
ActualException = MException.empty;
end
methods
function constraint = ThrowsErr(exception, numargout)
narginchk(1,2);
if nargin < 2, numargout = 0; end
validateattributes(exception, {'MException'}, {'scalar'}, '', 'exception');
validateattributes(numargout, {'numeric'}, {'scalar', '>=',0, 'nonnegative', 'integer'}, '', 'numargout');
constraint.ExpectedException = exception;
constraint.FcnNargout = numargout;
end
end
%% overriden methods for Constraint class
methods
function tf = satisfiedBy(constraint, actual)
tf = false;
% check that we have a function handle
if ~constraint.isFunction(actual)
return
end
% execute function (remembering that its been called)
constraint.invoke(actual);
% check if it never threw an exception
if ~constraint.HasThrownAnException()
return
end
% check if it threw the wrong exception
if ~constraint.HasThrownExpectedException()
return
end
% if we made it here then we passed
tf = true;
end
function diag = getDiagnosticFor(constraint, actual)
% check that we have a function handle
if ~constraint.isFunction(actual)
diag = constraint.getDiagnosticFor@matlab.unittest.internal.constraints.FunctionHandleConstraint(actual);
return
end
% check if we need to execute function
if constraint.shouldInvoke(actual)
constraint.invoke(actual);
end
% check if it never threw an exception
if ~constraint.HasThrownAnException()
diag = constraint.FailingDiagnostic_NoException();
return
end
% check if it threw the wrong exception
if ~constraint.HasThrownExpectedException()
diag = constraint.FailingDiagnostic_WrongException();
return
end
% if we made it here then we passed
diag = PassingDiagnostic(constraint);
end
end
%% overriden methods for FunctionHandleConstraint class
methods (Hidden, Access = protected)
function invoke(constraint, fcn)
outputs = cell(1,constraint.FcnNargout);
try
[outputs{:}] = constraint.invoke@matlab.unittest.internal.constraints.FunctionHandleConstraint(fcn);
constraint.ActualException = MException.empty;
catch ex
constraint.ActualException = ex;
end
end
end
%% private helper functions
methods (Access = private)
function tf = HasThrownAnException(constraint)
tf = ~isempty(constraint.ActualException);
end
function tf = HasThrownExpectedException(constraint)
tf = metaclass(constraint.ActualException) <= metaclass(constraint.ExpectedException) && ...
strcmp(constraint.ActualException.identifier, constraint.ExpectedException.identifier) && ...
strcmp(constraint.ActualException.message, constraint.ExpectedException.message);
end
function diag = FailingDiagnostic_NoException(constraint)
import matlab.unittest.internal.diagnostics.ConstraintDiagnosticFactory;
import matlab.unittest.internal.diagnostics.DiagnosticSense;
subDiag = ConstraintDiagnosticFactory.generateFailingDiagnostic(...
constraint, DiagnosticSense.Positive);
subDiag.DisplayDescription = true;
subDiag.Description = 'The function did not throw any exception.';
subDiag.DisplayExpVal = true;
subDiag.ExpValHeader = 'Expected exception:';
subDiag.ExpVal = sprintf('id = ''%s''\nmsg = ''%s''', ...
constraint.ExpectedException.identifier, ...
constraint.ExpectedException.message);
diag = constraint.generateFailingFcnDiagnostic(DiagnosticSense.Positive);
diag.addCondition(subDiag);
end
function diag = FailingDiagnostic_WrongException(constraint)
import matlab.unittest.internal.diagnostics.ConstraintDiagnosticFactory;
import matlab.unittest.internal.diagnostics.DiagnosticSense;
if strcmp(constraint.ActualException.identifier, constraint.ExpectedException.identifier)
field = 'message';
else
field = 'identifier';
end
subDiag = ConstraintDiagnosticFactory.generateFailingDiagnostic(...
constraint, DiagnosticSense.Positive, ...
sprintf('''%s''',constraint.ActualException.(field)), ...
sprintf('''%s''',constraint.ExpectedException.(field)));
subDiag.DisplayDescription = true;
subDiag.Description = sprintf('The function threw an exception with the wrong %s.',field);
subDiag.DisplayActVal = true;
subDiag.DisplayExpVal = true;
subDiag.ActValHeader = sprintf('Actual %s:',field);
subDiag.ExpValHeader = sprintf('Expected %s:',field);
diag = constraint.generateFailingFcnDiagnostic(DiagnosticSense.Positive);
diag.addCondition(subDiag);
end
function diag = PassingDiagnostic(constraint)
import matlab.unittest.internal.diagnostics.ConstraintDiagnosticFactory;
import matlab.unittest.internal.diagnostics.DiagnosticSense;
subDiag = ConstraintDiagnosticFactory.generatePassingDiagnostic(...
constraint, DiagnosticSense.Positive);
subDiag.DisplayExpVal = true;
subDiag.ExpValHeader = 'Expected exception:';
subDiag.ExpVal = sprintf('id = ''%s''\nmsg = ''%s''', ...
constraint.ExpectedException.identifier, ...
constraint.ExpectedException.message);
diag = constraint.generatePassingFcnDiagnostic(DiagnosticSense.Positive);
diag.addCondition(subDiag);
end
end
end
这是一个示例用法(使用与之前相同的功能):
t = matlab.unittest.TestCase.forInteractiveUse;
ME = MException('increment:NonNumeric', 'Input must be numeric.');
t.verifyThat(@()increment('5'), ThrowsErr(ME))
ME = MException('MATLAB:TooManyOutputs', 'Too many output arguments.');
t.verifyThat(@()increment(5), ThrowsErr(ME,2))
自从我发布这个答案以来,一些类的内部结构发生了一些变化。我更新了上面的代码以使用最新的 MATLAB R2016a。如果您想要旧版本,请查看修订历史。
关于matlab - 如何编写一个单元测试断言来检查具有指定标识符和特定消息的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17401971/
我需要根据需要动态设置文本区域,但它不想正常工作。 JQuery 会自行检查,但无法检查是否已检查。但是当您在第二个单选框内单击时,始终需要文本区域。我尝试了很多次让它工作,但它仍然有问题。我添加了“
我需要在 Django 中进行 API 调用(某种形式),作为我们所需的自定义身份验证系统的一部分。用户名和密码通过 SSL 发送到特定 URL(对这些参数使用 GET),响应应该是 HTTP 200
我将在我的可移植 C 代码中使用 #warning 来生成编译时警告。但并非所有平台都支持 #warning。有什么方法可以找到该平台是否支持 #warning。 #ifdef warning
我编写了一个函数来检查某个数字是否存在于某个区间内。停止搜索的最佳方法是什么?这个: for (i = a; i <= b; i++) { fi = f(i); if (fi == c) {
我想知道在 c 中是否有一种方法可以检查,例如在 for 函数中,如果变量等于或不等于某些字符,而不必每次都重复进行相等性检查。如果我没记错的话,以这种方式检查相等性是不正确的: if (a == (
我有如下日志功能 void log_error(char * file_name, int line_num, int err_code) { printf("%s:%d:%s\n", fil
使用 ssh-keygen 生成的 key 对在 macOS 上可以有不同的格式。 macOS 可读的标准 PEM ASN.1 对象 SecKey API 带有文本标题的 PEM OpenSSH ke
我正在尝试编写一个 excel if 语句。我不熟悉使用 Excel 具有的所有额外功能。我正在使用一个名为 importXML() 的函数.我正在尝试检查我正在使用的函数是否生成“#VALUE!”错
有没有办法检查是否没有 AIO 写入给定文件?我在我的 Unix 类(class)上制作了一个项目,该项目将是一个上下文无关(基于 UDP)的国际象棋服务器,并且所有数据都必须存储在文件中。应用程序将
我有一个如下所示的函数: public Status execute() { Status status = doSomething(); if (status != Stat
我正在使用 Composer,我不希望 PhpStorm 在 vendor 文件夹上运行任何错误检查或检查,因为它对 vendor/中的某些代码显示误报composer/autoload_static
Chapel 的一个很好的特性是它区分了数组的域和它的分布。检查两个数组是否具有相同的域和分布(通常想要的)的最佳方法是什么? 我能看到的最好的方法是检查 D1==D2和 D1.dist==D2.di
在我的 JavaScript 函数中,我为所有输入、文本区域和选择字段提供实际值作为 initial_value: $('input, textarea, select').each(function
我正在编写一个分解为几个简单函数的 PHP 类。在构造函数中,它调用另一个名为 processFile 的函数。该函数调用 5 个私有(private)函数并进行检查。如果检查失败,它会将消息分配给
这个问题已经有答案了: How to detect if user it trying to open a link in a new tab? (2 个回答) 已关闭 7 年前。 我认为 JavaS
我正在浏览我们的代码库并看到很多这样的测试: declare @row_id int = ... declare @row_attribute string select @row_attribu
我正在声明一个用作比较的函数。我的问题是: 为什么条件充当语句? 为什么第 4 行可以工作,而第 5 行却不行? 我知道这段代码不切实际且未使用,但为什么编译器允许这种语法? 谷歌没有找到答案。但话又
到目前为止,我有一个带有空文本字段的 PHP Kontaktform,并使用以下命令检查了所需的字段: $name = check_input($_POST['name'], "请输入姓名。"); 现
目前,我能想到的合理检查的唯一方法没有臃肿的逻辑: if ( $value > 0 ) { // Okay } else { // Not Okay } 有没有更好的办法? 最佳答案
我正在尝试运行一个脚本,如果 i 存在(意味着存在 i 值,任何值)或其他部分,我希望运行其中的一部分如果i没有值就运行,有人可以启发我吗? 我说的是 for 循环,比如 for (var i=0;
我是一名优秀的程序员,十分优秀!