假设我有一些文件a.rkt:
#lang racket
(define a 12)
Run Code Online (Sandbox Code Playgroud)
我现在想要编写一些测试用例,使用b.rkt需要的文件a.rkt:
#lang racket
(require "a.rkt")
a
Run Code Online (Sandbox Code Playgroud)
有没有什么方法可以b.rkt识别定义的标识符a.rkt而不必provide从第一个文件中获取?(理想情况下,根本不需要更改第一个文件.)
我在require/provide的文档中没有立即看到任何内容.
正如Leif所提到的,RackUnit require/expose 将允许在其他模块中使用未提供的标识符,但是它自己的文档不能保证非常有力的保证:
请注意,
require/expose可能有点脆弱,特别是与编译代码混合时.使用风险自负!
另一种方法是使用子模块,它可以有效地提供一种制裁方式来导出私有API,以便在测试或其他方法中使用.
例如,考虑一个实现函数的模块来测试字符串是否包含单个单词:
#lang racket
(provide word?)
(define (word? str)
(not (ormap space? (string->list str))))
(define (space? c)
(eq? c #\space))
Run Code Online (Sandbox Code Playgroud)
(这也许不是最现实的例子,但请耐心等待.)
测试space?函数以确保其有效可能很有用,但它可能不应该是公共API的一部分.要创建"逃生舱口",可以定义导出此绑定的子模块:
(module+ for-testing
(provide space?))
Run Code Online (Sandbox Code Playgroud)
这个名字for-testing是任意的 - 它可以是任何东西.无论哪种方式,现在可以要求另一个模块中的子模块访问私有绑定:
#lang racket
(require rackunit
(submod "a.rkt" for-testing))
(check-true (space? #\space))
(check-false (space? #\a))
Run Code Online (Sandbox Code Playgroud)
这是从模块公开标识符而不将其暴露给所有消费者的更安全的方式.
您可以使用require/exposein b.rkt来访问绑定a.rkt.b.rkt看起来像这样:
#lang racket
(require rackunit)
(require/expose "a.rkt" (a))
a
Run Code Online (Sandbox Code Playgroud)