为什么使用Rackunit进行此测试不起作用?

时间:2016-11-17 21:53:19

标签: unit-testing lisp racket

我正在使用Racket和Dr. Racket进行教育。

我正在尝试了解values内置函数。

当我使用以下输入调用值时,我得到此输出:

> (values 'this 'and-this 'and-that)
'this
'and-this
'and-that

为什么这个测试失败了?

#lang racket

(require rackunit racket/trace)

(check-equal? (values 'this 'and-this 'and-that) 'this 'and-this 'and-that)

2 个答案:

答案 0 :(得分:1)

由于values正在返回multiple values,而check-equal?无法处理,因此需要比较两个值。例如,这可行,因为我们只处理两个值:

(check-equal? (values 42) 42)

尝试不同的方法,我们先说我们首先解压缩多个值并将它们放在一个列表中:

(check-equal?
 (let-values ([(a b c) (values 'this 'and-this 'and-that)])
   (list a b c))
 '(this and-this and-that))

答案 1 :(得分:1)

您可以将多个值转换为列表,然后将其与预期值进行比较:

(define-syntax values->list
  (syntax-rules ()
    ((_ expr) 
     (call-with-values (lambda () expr) 
                       list))))

(check-equal? (values->list (values 'this 'and-this 'and-that))
              (list 'this 'and-this 'and-that))

values非常特别。它与call-with-values联系在一起。实际上它与listapply几乎相同,但没有在两者之间创建缺点。因此只是一个优化。在使用堆栈的实现中,它将返回堆栈上的值,而call-with-values将仅应用于应用thunk时获得的相同帧。

我认为Common Lisp版本更有用,因为它允许在单值的情况下使用多个值过程,只使用第一个值。在Scheme方言中,您需要使用call-with-values或使用它的宏或过程来处理多个值,这些值不太灵活,但也许可以使其他调用稍微更有效。