Search code examples
unit-testingchicken-scheme

chicken scheme - how do i temporarily capture data sent to standard output


I have a procedure that calls (display "foo")

I want to write a unit test for it, to confirm that it's sending the correct data there but display sends its input to Standard Output:

(define (display x #!optional (port ##sys#standard-output))
  (##sys#check-output-port port #t 'display)
  (##sys#print x #f port) )

Question: In other languages I might redefine standard output as something that just writes to a variable, and then set it back after the test. Is that the correct thing to do in chicken ? If so, how? If not, then what is the correct thing to do?

Note: passing something else in to display as a second parameter isn't an option because i'd have to alter the method I'm unit testing to do so.


Solution

  • The port is an optional second argument which defaults to standard output.

    You can do one of two things to send it to a string. The first way is to create a string port and pass it to display as the optional argument to use instead of the standard output port:

    (use ports)
    (call-with-output-string
      (lambda (my-string-port)
        (display "foo" my-string-port)))
    

    The second is to temporarily bind the current output port to a string port:

    (use ports)
    (with-output-to-string
      (lambda () (display "foo")))
    

    The second way is mostly useful when you're calling procedures that don't accept a port argument, like print, for example.

    You can find this in the manual section about string ports.