0

I'm attempting write a test for my package and failing at comparing funcs. Here's essentially what i'm doing.

package main

import (
    "fmt"
    "reflect"
)

type HandlerFunc func(cmd interface{})

type Bus struct {
    handlers map[reflect.Type]HandlerFunc
}

func (bus *Bus) RegisterHandler(cmd interface{}, handler HandlerFunc) {
    bus.handlers[reflect.TypeOf(cmd)] = handler
}

func (bus *Bus) GetHandler(cmd interface{}) HandlerFunc {
    t := reflect.TypeOf(cmd)

    for kind, handler := range bus.handlers {
        if t == kind {
            return handler
        }
    }

    return nil
}

func New() *Bus {
    return &Bus{
        handlers:    make(map[reflect.Type]HandlerFunc),
    }
}

type RegisterUserCommand struct {}

func main() {
    bus := New()
    handler := func (cmd interface{}) {}

    bus.RegisterHandler(&RegisterUserCommand{}, handler)

    retrieved := bus.GetHandler(&RegisterUserCommand{})

    if retrieved != handler {
        fmt.Println("Not the same!")
        return
    }

    fmt.Println("Same!")
}

Comparing retrieved with handler causes the following error

invalid operation: (func(interface {}))(retrieved) != handler (func can only be compared to nil)

How can i properly test the function i'm retrieving is the same one added previously?

David
  • 10,418
  • 17
  • 72
  • 122
  • This is not an answer to your actual question, but why do you iterate through the map of types to handlers in `GetHandler`? You can return `bus.handlers[t]` and that will return `nil` for undefined handlers. – Matt K Apr 29 '15 at 03:11
  • @mkb because i'm dumb haha – David Apr 29 '15 at 03:12
  • possibly related to http://stackoverflow.com/questions/9643205/how-do-i-compare-two-functions-for-pointer-equality-in-the-latest-go-weekly – Dave C Apr 29 '15 at 03:19

1 Answers1

4

Given that you can't compare functions, you can write your test in a different way. You can make handler set a boolean value in your test and check that you've got the right function by calling it and seeing if the boolean changes.

Here's an example:

func main() {
    bus := New()
    called := false
    handler := func (cmd interface{}) { called = true }

    bus.RegisterHandler(&RegisterUserCommand{}, handler)
    bus.GetHandler(&RegisterUserCommand{})(nil)

    if called {
        fmt.Println("We got the right handler!")
        return
    }

    fmt.Println("We didn't get the right handler")
}
Paul Hankin
  • 54,811
  • 11
  • 92
  • 118