Checking for panic condition in test cases

Often when we write functions, we encounter panic situations, where a program must throw a panic which will be (Hopefully) handled by some other part of the system. More on panic and recover here.

Consider a function which triggers a panic situation

func triggerPanic(token string) {	
     panic("A panic situation is encountered")
}

Now, while testing we want to ensure that this panic is indeed triggered. Here is how we can test for the Panic condition

func TestDeleteCredentials(t *testing.T) {
	var err interface {}
	defer func() {
		if err = recover(); err != nil {
                 fmt.Println("We are in recover but we have an error", err)
		}
		assert.NotNil(t, err, "Function has failed")
		assert.Equal(t, "A panic situation is encountered", err, "May be correct panic has not been called!")
	}()
	triggerPanic("dummy token")

}

In this test case, we have our assert statements inside the defer, to ensure that once we are able to recover from Panic, we can assert that a panic was indeed called and we check message that the correct panic was called!

Another way of checking for panic, pointed out in this reddit thread

func panics(doesItPanic func(s string)) (r interface{}) {
	defer func() {
		r = recover()
	}()
	doesItPanic("string")
	return
}

func TestDeleteCredentials(t *testing.T) {
	r := panics(triggerPanic)
	assert.NotNil(t, r, "Panic did not occur")
}

Here we created a function panics(), which accepts a function as parameter and checks whether that function panics or not. A much cleaner approach then the first one!

Let me know, what you think or in case have a better way of doing this.

Have a good time, Gopher!

~~ Whizdumb ~~
Email : sachin.xpert@gmail.com