user7120460
user7120460

Reputation:

Unit-testing in Racket with multiple outputs

I am trying to use unit-tests with Racket.

Usually, I am successful and I really like rackunit. However, I am having trouble with this specific case.

The function to be tested outputs two values. How can I test this using rackunit?

When I call:

(game-iter 10)
>>  5 10

I tried using this test:

(check-equal? (game-iter 10) 5 10)

However, it fails:

. . result arity mismatch;
 expected number of values not received
  expected: 1
  received: 2
  values...:

Upvotes: 6

Views: 533

Answers (3)

xiaoyu2006
xiaoyu2006

Reputation: 545

@Winny 's answer is not working for me. However I find this useful:

(define-syntax check-values-equal?
    (syntax-rules ()
      [(_ a b) (check-equal? (call-with-values (lambda () a) list)
                             (call-with-values (lambda () b) list))])))

Upvotes: 0

Winny
Winny

Reputation: 1278

A simple macro approach

@Gibstick's answer is right on, but I wanted to illustrate a more general approach that somebody on the #racket irc channel gave to me many months ago:

(define-syntax check-values-equal?
  (syntax-rules ()
    [(_ a b) (check-equal? (call-with-values (thunk a) list)
                           b)]))

You'd use it like this:

(check-values-equal? (game-iter 10) '(5 10))

There is some room for improvement (such as adding support for the third argument of the check-equal? macro, however, I find this works well enough.

Upvotes: 2

Gibstick
Gibstick

Reputation: 737

I couldn't find anything that already exists, so I came up with the long way to do it. If you don't have many functions that return multiple values, you could do something like

(define-values (a b) (game-iter 10))
(check-equal? a 5)
(check-equal? b 10)

You can pick better names for a and b.

You can abstract this somewhat with something like:

;; check if (game-iter n) produces (values a-expect b-expect)
(define-simple-check (check-game-iter n a-expect b-expect)
  (define-values (a b) (game-iter n))
  (and (equal? a a-expect)
       (equal? b b-expect)))
(check-game-iter 10 5 10)

(Again, pick better names than a b.)

If you want to make this even more general, take a look at call-with-values.

Upvotes: 2

Related Questions