【问题标题】:In SML, how to assert that a particular exception is thrown?在 SML 中,如何断言抛出了特定的异常?
【发布时间】:2011-05-13 18:12:10
【问题描述】:

在没有实际克隆 JUnit 或其他东西的情况下,我将一些实用函数放在一起来帮助测试一些 SML 代码。我确实知道 QCheck,但它也不能做这件事,也不是我通常想要的。 (但如果您知道另一个 SML 自动化测试框架,请说出来。)

我希望能够断言某些函数会抛出异常,例如,给定一个函数

fun broken x = raise Fail

我希望能够写出类似的东西

throws ("ERROR: function is not broken enough!", fn () => broken 1, Fail)

如果给定函数没有引发预期的异常,则让它抛出错误。

我尝试编写一个throws 类型为(string * exn * (unit -> unit)) -> unit 的函数,如下所示:

  fun throws (msg, e, func) = func ()
    handle e' => if e = e'
                     then ()
                     else raise ERROR (SOME msg)

但这会产生一堆编译时错误,显然是因为 ML 没有定义例外的平等:

sexp-tests.sml:54.31-57.49 Error: types of rules don't agree [equality type required]
  earlier rule(s): ''Z -> unit
  this rule: exn -> 'Y
  in rule:
    exn => raise exn
sexp-tests.sml:54.31-57.49 Error: handler domain is not exn [equality type required]
  handler domain: ''Z
  in expression:
    func ()
    handle 
        e' => if e = e' then () else raise (ERROR <exp>)
    | exn => raise exn

作为一种解决方法,我怀疑我可以重用现有的 assert 函数:

assert ((broken 1; false) handle Fail => true | _ => false)

但它需要更多的思考和打字。

那么,有没有办法在 SML 中编写 throws 函数?

【问题讨论】:

    标签: exception testing equality sml


    【解决方案1】:

    以下功能应该可以工作:

    exception ERROR of string option;
    
    fun throwError msg = raise ERROR (SOME msg);
    
    fun throws (msg, func, e) =
        (func (); throwError msg) handle e' =>
            if exnName e = exnName e'
            then ()
            else raise throwError msg
    

    这使用了函数exnName,它将异常的名称作为字符串获取,并使用它来进行比较。

    更重要的是,它还处理了根本没有抛出异常的情况,并且也给出了错误。

    或者,如果您只需要一个布尔值,指示是否抛出异常,您可以使用:

    fun bthrows (func, e) = (func (); false) handle e' => exnName e = exnName e'
    

    请注意,对于失败的情况,您实际上必须创建一个失败异常的实例,例如:

    throws ("ERROR: Oh no!", fn () => test 5, Fail "")
    

    或者,您可以使用异常的名称,以便更简洁的一般情况:

    fun throws (msg, func, e) =
        (func (); throwError msg) handle e' =>
            if e = exnName e'
            then ()
            else raise throwError msg
    
    fun bthrows (func, e) = (func (); false) handle e' => e = exnName e'
    

    然后像这样使用它:

    throws ("ERROR: Oh no!", fn () => test 5, "Fail")
    

    【讨论】:

      猜你喜欢
      • 2019-09-03
      • 2017-03-09
      • 2011-08-06
      • 1970-01-01
      • 2023-01-11
      • 1970-01-01
      • 2022-06-16
      • 2018-03-19
      相关资源
      最近更新 更多