In the past when I wanted to 'capture' the log output so that I could check it in a unit test I would 'hijack' os.Stdout like so
```
var osStdout = os.Stdout
func MyCode (){
log.SetOutput(osStdout)
log.Print("My dog has fleas")
}
```
Which could then be tested thus
```
func TestMyCode(t *testing.T){
testcases := map[string]struct{
output string
}{
"Dog needs flea shampoo": {
output: "My dog has fleas",
},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
orig := osStdout
flags := log.Flags()
log.SetFlags(0)
reader, writer, err := os.Pipe()
if err != nil {
panic(err)
}
osStdout = writer
defer func() {
osStdout = orig
log.SetFlags(flags)
}()
MyCode()
writer.Close()
var buf strings.Builder
if _, ioerr := io.Copy(&buf, reader); ioerr != nil {
log.Fatalf("Copy error, cannot continue %v\n", ioerr)
}
assert.Equal(t, tc.output, buf.String(), "Expected: %s Got: %s", tc.output, buf.String())
}
})
}
}
```
I'm now trying to do the same with the slog package (but not having any joy) - is there an established pattern that people are using, eg. is the handler being
I've been trying
```
func TestMyCode(t *testing.T){
testcases := map[string]struct{
output string
}{
"Dog needs flea shampoo": {
output: "My dog has fleas",
},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
orig := osStdout
reader, writer, err := os.Pipe()
if err != nil {
panic(err)
}
osStdout = writer
defer func() {
osStdout = orig
}()
slog.SetDefault(slog.New(slog.NewTextHandler(osStdout)
MyCode()
writer.Close()
var buf strings.Builder
if _, ioerr := io.Copy(&buf, reader); ioerr != nil {
log.Fatalf("Copy error, cannot continue %v\n", ioerr)
}
assert.Equal(t, tc.output, buf.String(), "Expected: %s Got: %s", tc.output, buf.String())
}
})
}
}
```
Which "works" but I am not happy with it, because it's affecting all of the slog instances.
I saw previously that someone was creating their own implementation of a slog.Handler? to make testing easier, and would love to see it, and will that allow me to run multiple slog based tests concurrently?