如何在goroutine中测试监视文件的功能

I have a function that watches certian file via fsnotify and calls a callback when the file changes. If the callback returns false, the watching is ended:

import (
    "github.com/golang/glog"
    "github.com/fsnotify/fsnotify"
)

type WatcherFunc func(err error) bool

func WatchFileChanges(filename string, watcherFunc WatcherFunc) {
    watcher, err := fsnotify.NewWatcher()

    if err != nil {
        glog.Errorf("Got error creating watcher %s", err)
    }

    defer watcher.Close()

    done := make(chan bool)

    go func() {
        for {
            select {
            case event := <-watcher.Events:
                glog.Infof("inotify event %s", event)

                if event.Op&fsnotify.Write == fsnotify.Write {
                    glog.Infof("modified file %s, calling watcher func", event.Name)

                    if !watcherFunc(nil) {
                        close(done)
                    }
                }

            case err := <-watcher.Errors:
                glog.Errorf("Got error watching %s, calling watcher func", err)

                if !watcherFunc(err) {
                    close(done)
                }
            }
        }
    }()

    glog.Infof("Start watching file %s", filename)

    err = watcher.Add(filename)

    if err != nil {
        glog.Errorf("Got error adding watcher %s", err)
    }
    <-done
}

Then I thought it would be nice to have a test for that, so I started out with a simple test case:

import (
    "io/ioutil"
    "os"
    "testing"
)

func TestStuff(t *testing.T) {
    tmpfile, err := ioutil.TempFile("", "test")

    if err != nil {
        t.Fatal("Failed to create tmp file")
    }

    defer os.Remove(tmpfile.Name())

    watcherFunc := func (err error) bool {
        return false
    }

    WatchFileChanges(tmpfile.Name(), watcherFunc)
}

What I wanted do to here is to do a few modifications to the file, collect the events in an array, return then false from the watcherFunc and then assert on the array. The thing is, of course the test just hangs and waits for events, as the goroutine was started.

Is there any way how I can test a function like this, like … starting a different thread (?) that updates/modifies the file?

Is there any way how I can test a function like this, like … starting a different thread (?) that updates/modifies the file?

Of course... start a goroutine that does the updates you want.

func TestStuff(t *testing.T) {
    tmpfile, err := ioutil.TempFile("", "test")

    if err != nil {
        t.Fatal("Failed to create tmp file")
    }

    defer os.Remove(tmpfile.Name())

    watcherFunc := func (err error) bool {
        return false
    }
    go func() {
        // Do updates here
    }()

    WatchFileChanges(tmpfile.Name(), watcherFunc)
}