Testing Stdin Stdout
I needed to test the input and output of a cli program I was writing.
I needed to capture what was happening in a goroutine safe way so I ended up with the struct below.
Anywhere that did logging was passed this struct as their io.Writer
It has a lock as testing with -race
complained (rightly) at multiple routines trying to access at once. This would also help ensure that messages were output in full, without interference from other write calls
E
The only other concern was that as it was a buffered output, you need to call flush before getting a string of the output to compare.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| type StdIO struct {
in bytes.Buffer
out bytes.Buffer
inReader *bufio.Reader
outWriter *bufio.Writer
rMutex sync.Mutex
wMutex sync.Mutex
}
func (s *StdIO) Flush() {
s.wMutex.Lock()
defer s.wMutex.Unlock()
s.outWriter.Flush()
}
func (s *StdIO) Read(p []byte) (n int, err error) {
s.rMutex.Lock()
defer s.rMutex.Unlock()
return s.inReader.Read(p)
}
func (s *StdIO) Write(p []byte) (n int, err error) {
s.wMutex.Lock()
defer s.wMutex.Unlock()
return s.outWriter.Write(p)
}
func NewStdIO() *StdIO {
s := &StdIO{
in: bytes.Buffer{},
out: bytes.Buffer{},
}
s.inReader = bufio.NewReader(&s.in)
s.outWriter = bufio.NewWriter(&s.out)
return s
}
|