Reputation: 38879
I have go test code similar to this:
func TestRollback(t *testing.T) {
store := NewStore()
// do some stuff
err := store.Rollback()
// checks
}
The problem is store.Rollback() has a prompt read from the stdin for y or n
How do I send "y" to the test process when running go test -v --run TestRollback
Upvotes: 2
Views: 763
Reputation: 66183
The difficulty in testing your Rollback
method stems from hardcoding its dependency on singleton os.Stdin
.
Tinkerer's answer is viable but, because it mutates that package-level variable, it doesn't lend itself to running tests in parallel.
A preferable alternative (IMO) consists in using an interface. Testing often rhymes with interface, in Go. Here, because os.Stdin
satisfies the io.Reader
interface, you could parameterise your Store
type with an io.Reader
passed to your factory function:
type Store struct {
// other fields, omitted here
in io.Reader
}
func NewStore(in io.Reader) *Store {
store := Store {
// other fields, omitted here
in: in,
}
return &store
}
Then, in your test functions, you could use a concrete type that satisfies io.Reader
and is easily configurable, such as a *strings.Reader
:
func TestRollback(t *testing.T) {
// arrange
in := strings.Reader("-- put contents of stdin here --")
store := NewStore(in)
// act
err := store.Rollback()
// assert
// ...
}
Upvotes: 2
Reputation: 1068
The following can redirect stdin temporarily.
rd,wr,err := os.Pipe()
saved := os.Stdin
os.Stdin = rd
... Test code feeds wr ...
os.Stdin = saved
Upvotes: 1