包非常非常基础。 循环遍历游标,并更新record_ids相等的2个值。
对于这种程序,什么是适当的单元测试?
我将添加一些骷髅代码,因为到目前为止答案虽然很好,但却与我的问题紧密相关:我该测试什么?
PROCEDURE set_shift_times_to_null( RETVAL OUT VARCHAR2,
ERRBUF OUT VARCHAR2,
RECORDS_UPDATED OUT NUMBER) IS
CURSOR evening_shift_employees_cur IS
select employee
FROM employees
where SHIFT='EVENING'
;
BEGIN
RECORDS_UPDATED := 0;
RETVAL := '2';
FOR evening_shift_employees IN evening_shift_employees_cur LOOP
UPDATE NIGHT_SHIFT
Set SOME_DUMB_FIELD = evening_shift_employees.employee;
RECORDS_UPDATED := RECORDS_UPDATED + 1;
END LOOP;
COMMIT;
RETVAL := 0;
EXCEPTION WHEN OTHERS THEN
ROLLBACK;
ERRBUF := 'Error occurred - ' || SQLERRM;
END set_shift_times_to_null;
答案 0 :(得分:1)
适当的单元测试它以验证受影响的表以检查更新的记录是否符合预期。
您可以使用期望的结果创建临时表,并且单元测试代码可以比较结果。当然是努力工作,但如果你想测试你必须做这样的事情。
这取决于程序的工作,但如果你想确保测试没问题,你必须尽可能检查。
许多条件必须使用约束进行验证,并且测试单元过程必须执行强制数据库检查约束(插入等)的代码。
答案 1 :(得分:1)
一些建议。
使用SQL%ROWCOUNT:
BEGIN
UPDATE NIGHT_SHIFT
Set SOME_DUMB_FIELD = evening_shift_employees.employee;
v_rows_processed := SQL%ROWCOUNT;
dbms_output.put_line('There were '||v_rows_processed||' rows updated');
END;
不要在其他人使用时(为什么要丢失堆栈跟踪)。只能使用例外,您将依赖调用者来检查ERRBUF的内容。
begin
insert into t values ( 1 );
exception when others then
log_error;
raise;
end;
log_error实现如下:
create or replace procedure log_error
as
pragma autonomous_transaction;
l_whence varchar2(1024);
l_msg varchar2(1020) default sqlerrm;
l_code number default sqlcode;
begin
l_whence := whence;
insert into error_table
( timestamp, whence, msg, code )
values
( sysdate, whence, l_msg, l_code );
commit;
exception
when others then
rollback;
raise;
end;
考虑不使用任何pl / sql。在表面上,更新看起来完全“可行”而没有任何光标。也许是一个可更新的内联视图:
update (
select e.sal as emp_sal, e.comm as emp_comm,
ns.sal as ns_sal, ns.sal/2 as ns_comm
from employees e, night_shift ns
where e.deptno = ns.deptno
)
set emp_sal = ns_sal, emp_comm = ns_comm
答案 2 :(得分:0)
基本上,您希望锻炼手术的所有可能性:
另外,测试边界条件:
这是一个很好的example良好的单元测试实践。
编辑:我不知道有一个强大的数据库查询单元测试工具。我会设置一个 evening_shift_employees 的测试表,其中包含各种记录ID条件,如上所述。然后,按照FerranB的建议,检查记录是否按预期进行更新以进行验证。答案 3 :(得分:0)
我最终做的是以下内容:
这是否有意义,还是循环逻辑?
答案 4 :(得分:0)
对于其他任何看过这个的人,我在utplsql的文档中找到了这个: 程序utAssert.eqtable(
msg_in IN VARCHAR2,
check_this_in IN VARCHAR2,
against_this_in IN VARCHAR2,
check_where_in IN VARCHAR2 := NULL,
against_where_in IN VARCHAR2 := NULL,
raise_exc_in IN BOOLEAN := FALSE
);
这是断言文件;看起来它完全符合我的目的。