proposal: testing: expose a constructor for *testing.T #28021
Closed
Labels
Milestone
Comments
Consider making the function take a |
OH. thanks @acln0 that's what i was looking for, closing this issue. |
wait, you cannot implement testing.TB, due to an unexported |
When I've needed to write a fake testing.TB, I've just gone ahead and included an embedded type tb struct {
name string
mu sync.Mutex
output []string
skipped, failed bool
// The testing.TB interface has an unexported method "to prevent users implementing the
// interface and so future additions to it will not violate Go 1 compatibility."
//
// This may cause problems across Go versions, but let's ignore them and
// work around that restriction by embedding a T so we satisfy the unexported methods of the interface.
*testing.T
}
var _ testing.TB = (*tb)(nil)
func (t *tb) Error(args ...interface{}) {
t.Log(args...)
t.Fail()
}
func (t *tb) Errorf(format string, args ...interface{}) {
t.Logf(format, args...)
t.Fail()
}
func (t *tb) Fail() {
t.mu.Lock()
t.failed = true
t.mu.Unlock()
}
func (t *tb) FailNow() {
t.Fail()
runtime.Goexit()
}
func (t *tb) Failed() bool {
t.mu.Lock()
failed := t.failed
t.mu.Unlock()
return failed
}
func (t *tb) Fatal(args ...interface{}) {
t.Log(args...)
t.FailNow()
}
func (t *tb) Fatalf(format string, args ...interface{}) {
t.Logf(format, args...)
t.FailNow()
}
func (t *tb) Log(args ...interface{}) {
t.mu.Lock()
defer t.mu.Unlock()
t.output = append(t.output, fmt.Sprintln(args...))
}
func (t *tb) Logf(format string, args ...interface{}) {
t.mu.Lock()
defer t.mu.Unlock()
// Ensure message ends with newline.
if len(format) > 0 && format[len(format)-1] != '\n' {
format += "\n"
}
t.output = append(t.output, fmt.Sprintf(format, args...))
}
func (t *tb) Name() string {
return t.name
}
func (t *tb) Skip(args ...interface{}) {
t.Log(args...)
t.SkipNow()
}
func (t *tb) SkipNow() {
t.mu.Lock()
t.skipped = true
t.mu.Unlock()
runtime.Goexit()
}
func (t *tb) Skipf(format string, args ...interface{}) {
t.Logf(format, args...)
t.SkipNow()
}
func (t *tb) Skipped() bool {
t.mu.Lock()
skipped := t.skipped
t.mu.Unlock()
return skipped
}
func (t *tb) Helper() {} |
Another option is to have your function take a smaller interface than |
yess both of these solutions are great, thanks @mvdan and @mark-rushakoff 🙏🏽🙏🏽 I will just create my own interface and *testing.T will implement it. |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Can we expose a constructor that creates a minimal
*testing.T
? (..or even make T an interface)?I have some helpers which I use for ease of testing. e.g.
I was thinking about testing this Assert, by passing in a new
*testing.T
and checking ift.Failed()
but my code panics because T is unable to be initialized properly.The text was updated successfully, but these errors were encountered: