Mocking dependency behaviour in racket

Viewed 51

I'm just starting to use mocks in racket and I want to test the following code:

(define (tables #:connector [postgresql-connect postgresql-connect]
                     #:list-tables [list-tables list-tables])
  ; connect to the db
  (define pgc
    (postgresql-connect #:user "app_user"
                        #:database "test_database"
                        #:password "something_secure"))

  ; find all the tables
  (list-tables pgc))

So I have a couple test cases:

(module+ test
  (require rackunit)
  (require mock)
  (require mock/rackunit)
  
  (test-case "it returns a report structure"
    (check-eq? (sniffer "not://a.url/test") "not://a.url/test"))
  (test-case "it calls the db connector with the right arguments"
    (define connector-mock (mock #:behavior postgresql-connect))
    (sniffer "not://a.url/test" #:connector connector-mock)
    (check-mock-called-with? connector-mock (arguments #:database "test_database"
                                                       #:password "something_secure"
                                                       #:user "app_user")))
(test-case "it compiles a list of tables to examine"
    (define connector-mock (mock #:behavior postgresql-connect ))
    (define list-tables-mock (mock #:behavior list-tables ))
    
    (sniffer "not://a.url/test" #:connector connector-mock #:list-tables list-tables-mock)
    (check-mock-called-with? list-tables-mock (arguments connector-mock))))

When I run the tests I get:

--------------------
it calls the db connector with the right arguments
; ERROR


tcp-connect: connection failed
  hostname: localhost
  port number: 5432
  system error: Connection refused; errno=61
--------------------
--------------------
it compiles a list of tables to examine
; ERROR


tcp-connect: connection failed
  hostname: localhost
  port number: 5432
  system error: Connection refused; errno=61
--------------------

This leads me to this. How do I tell the mocks to mimic postgresql-connect without calling the actual implementation?

1 Answers

When you use the #:behavior keyword, you're saying that the mock should actually call that function. You're passing postgresql-connect, so the mock actually tries to connect. You will need to pass a different function that doesn't actually do the connection but takes the same arguments, perhaps with define-opaque from the mock library.

This example from the mock documentation may be helpful.

Related