Some reflective testing with gocheck

By: on September 30, 2011

Last time
I wrote about custom gocheck checkers and wrote a checker that checked if a
slice of int contained a specific int – it would be nice to have a generic
contains checker and using the go reflection we can write one.

Our earlier checker was built upon this function:

func contains(slice []int, value int) bool {
  for _, v := range slice {
    if v == value {
      return true
  return false

Go doesn’t have generics so we have to use reflection to build a contains
function that will work for a slice of any type. In go you define
"any" type using interface{}, the empty interface.
So we would like to build a function with this signature:

func contains(slice, value interface{}) bool

If we have a slice of int and we check if it contains a type that isn’t int
that should return false. We will write a small function to determine if a
slice or an array contains a specific type, this will be the first place we
use the reflect package to examine types. Here is the code:

func containsType(slice, value interface{}) bool {
  switch v := reflect.ValueOf(slice); v.Kind() {
  case reflect.Slice, reflect.Array:
    return v.Type().Elem() == reflect.TypeOf(value)
  return false

This function takes a slice and a value both of type interface{}
so they can hold any type. The switch and case statement check if the parameter
advertised as a slice is actually a slice, or an array. If that is true it
compares the type held by the slice with the type of the value. The real work
here is carried out by the reflect.Value struct returned by the reflect.ValueOf
function. The reflect.Value struct contains parameters which describe any go
type. In this function, Kind() allows us to determine that we have been given
an array or a struct, and Type().Elem() allows us to determine what type the
slice contains.

Now we can write the contains function like this:

func contains(slice, value interface{}) bool {
  if containsType(slice, value) {
    switch c := reflect.ValueOf(slice); c.Kind() {
    case reflect.Slice, reflect.Array:
      for i := 0; i < c.Len(); i++ {
        if reflect.DeepEqual(c.Index(i).Interface(), value) {
          return true

  return false

This uses the containsType function and is structured in a similar fashion.
The main magic is the reflect.DeepEqual function, this does a recursive equals
check with reflection across arbitary structures.

We can now replace the contains function in last months code and write some

func (s *S) TestContains(c *C) {
  a := []int{2, 3, 4}
  c.Check(a, Contains, a[0])
  c.Check(a, Contains, a[1])
  c.Check(a, Contains, a[2])
  c.Check(a, Contains, 2)
  c.Check(a, Contains, 3)
  c.Check(a, Contains, 4)
  c.Check(a, Not(Contains), 5)
  c.Check(a, Not(Contains), a)
  c.Check(a, Not(Contains), "x")


Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>