原文 我有下面的類:
class A {
int[] array;
...
void print() {
writeln("array = ", this.array);
}
}
是否可用
assert
來測試
print
函數,對
stdout
的輸出,如下?
A myClass= new A;
myClass.array = [1,2];
assert(myClass.print() == "array = [1,2]");
可重定向
stdout
到你選的檔案,再測試
該檔案
.
盡管最好按
參數
來列印某種
輸出區間
或
Appender
,然後再測試它.
最簡單
方法是
修改
函數,使其可
輸出
到非
stdout
,讓它輸出到
unittest
中的
一個檔案
,并檢查
檔案内容
來驗證結果.
如:
import std.stdio;
class A
{
int[] a;
this(int[] a) { this.a = a; }
void print(File output = stdout) {
output.writeln("array = ", this.a);
}//輸出
}
unittest {
import std.file;
A a = new A([1, 2]);
a.print(File("test.txt", "wb"));
assert(readText("test.txt") == "array = [1, 2]\n");
//斷定内容.
}
類似
PaulBackus
的程式,但我會盡量避免
單元測試
中使用
檔案系統
.這裡,可列印到
接收器(sink)
中:
import std.stdio;
class A
{
int[] a;
this(int[] a) { this.a = a; }
void toString(scope void delegate(in char[]) sink) const {
import std.conv : text;
sink("array = ");
sink(this.a.text);
// 或this.a.to!string
// 較重量級替代:
// import std.format : formattedWrite;
// sink.formattedWrite!"array = %s"(this.a);
}
void print() {
writeln(this);
}
}
unittest {
import std.file;
A a = new A([1, 2]);
import std.conv : text;
assert(a.text == "array = [1, 2]");
}
void main() {}
toString
是對象的
文本表示
.如果不想得到
相同輸出
,可用與
toString
不同的名,但這時必須使用
顯式
的
"sink"
,最好上面.
void myfunc(File = std.stdio.File)(File output = stdout) {
output.writeln(...);
}
unittest {
struct MockFile {
string output;
void writeln(Args...)(Args args) {
output ~= format(args);
}
}
MockFile mock;
myfunc(mock);
assert(mock.output == ...);
}
auto original = stdout; // 儲存
stdout.open(newdest, "wt"); // 重定向
// 幹活.
stdout = original; // 恢複