www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Unit testing a function returning void

reply Bruno Pagis <imnotsharing myaddress.com> writes:
Good morning,
I have the following class:

```
class A {
   int[] array;

   ...

   void print() {
     writeln("array = ", this.array);
   }
}
```

I would like to unit test the print function (yes, I know, not 
very useful on the above example since print is merely a 
duplicate of writeln...). Is there a way to use assert to test 
the output of the print function to stdout? Something like:
```
A myClass= new A;
myClass.array = [1,2];
assert(myClass.print() == "array = [1,2]"); // I know that print 
does not return anything so this is wrong, but you get the idea 
:-)
```
Thanks.
Nov 03 2022
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
You could redirect stdout to a file of your choosing and test against that.

Although ideally you would instead take as an argument to print some 
sort of output range or Appender. Then you could test against that instead.
Nov 03 2022
prev sibling next sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Thursday, 3 November 2022 at 10:00:27 UTC, Bruno Pagis wrote:
 Good morning,
 I have the following class:

 ```
 class A {
   int[] array;

   ...

   void print() {
     writeln("array = ", this.array);
   }
 }
 ```

 I would like to unit test the print function (yes, I know, not 
 very useful on the above example since print is merely a 
 duplicate of writeln...). Is there a way to use assert to test 
 the output of the print function to stdout? Something like:
 ```
 A myClass= new A;
 myClass.array = [1,2];
 assert(myClass.print() == "array = [1,2]"); // I know that 
 print does not return anything so this is wrong, but you get 
 the idea :-)
 ```
 Thanks.
Just so we understand, do you want to verify that the output is indeed directed to stdout and not some other stream?
Nov 03 2022
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Thursday, 3 November 2022 at 10:26:04 UTC, Imperatorn wrote:
 On Thursday, 3 November 2022 at 10:00:27 UTC, Bruno Pagis wrote:
 Good morning,
 I have the following class:

 ```
 class A {
   int[] array;

   ...

   void print() {
     writeln("array = ", this.array);
   }
 }
 ```

 I would like to unit test the print function (yes, I know, not 
 very useful on the above example since print is merely a 
 duplicate of writeln...). Is there a way to use assert to test 
 the output of the print function to stdout? Something like:
 ```
 A myClass= new A;
 myClass.array = [1,2];
 assert(myClass.print() == "array = [1,2]"); // I know that 
 print does not return anything so this is wrong, but you get 
 the idea :-)
 ```
 Thanks.
Just so we understand, do you want to verify that the output is indeed directed to stdout and not some other stream?
Just for documentation purposes, if you wished to redirect I believe you could do something like this (untested): ```d auto original = stdout; // save stdout.open(newdest, "wt"); // redirect // do stuff, check newdest stdout = original; // restore ```
Nov 03 2022
prev sibling next sibling parent Paul Backus <snarwin gmail.com> writes:
On Thursday, 3 November 2022 at 10:00:27 UTC, Bruno Pagis wrote:
 Good morning,
 I have the following class:

 ```
 class A {
   int[] array;

   ...

   void print() {
     writeln("array = ", this.array);
   }
 }
 ```

 I would like to unit test the print function (yes, I know, not 
 very useful on the above example since print is merely a 
 duplicate of writeln...). Is there a way to use assert to test 
 the output of the print function to stdout?
The easiest way to do this is to modify the function so it can output somewhere other than stdout. Then you can have it output to a file in the unittest, and check the contents of the file to verify the result. For example: ```d 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"); } ```
Nov 03 2022
prev sibling next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 11/3/22 03:00, Bruno Pagis wrote:

    void print() {
      writeln("array = ", this.array);
    }
Similar to Paul Backus's program but I would try to avoid the file system for unit tests when possible. In this case, you can print into a sink, which can be useful in other ways as well: 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); // or this.a.to!string // The following alternative may be a little heavier weight: // 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 is the textual representation of the object. If you don't want the same output for that purpose, you can use a different name from toString but you have to use an explicit "sink" but I really think the above is what you want. :) Ali
Nov 03 2022
parent "H. S. Teoh" <hsteoh qfbox.info> writes:
On Thu, Nov 03, 2022 at 08:51:52AM -0700, Ali Çehreli via Digitalmars-d-learn
wrote:
 On 11/3/22 03:00, Bruno Pagis wrote:
 
    void print() {
      writeln("array = ", this.array);
    }
Similar to Paul Backus's program but I would try to avoid the file system for unit tests when possible. In this case, you can print into a sink, which can be useful in other ways as well:
[...] Alternatively, you can templatize on File to make it swappable with a mock object: 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 == ...); } T -- "Maybe" is a strange word. When mom or dad says it it means "yes", but when my big brothers say it it means "no"! -- PJ jr.
Nov 03 2022
prev sibling parent Sergey <kornburn yandex.ru> writes:
On Thursday, 3 November 2022 at 10:00:27 UTC, Bruno Pagis wrote:
 Good morning,

 I would like to unit test the print function (yes, I know, not 
 very useful on the above example since print is merely a 
 duplicate of writeln...). Is there a way to use assert to test 
 the output of the print function to stdout? Something like:
Just for curiosity: we have this tremendous list of testing libraries https://code.dlang.org/search?q=test Maybe one of them has the 'capture stdout' (https://docs.pytest.org/en/7.1.x/how-to/capture-stdout-stderr.html) feature?
Nov 03 2022