如何测试在goroutine中监视文件的函数

时间:2017-04-18 09:31:20

标签: multithreading unit-testing go

我有一个通过fsnotify监视certian文件的函数,并在文件更改时调用回调函数。如果回调返回false,则观看结束:

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
}

然后我认为对它进行测试会很好,所以我从一个简单的测试用例开始:

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)
}

我想要做的就是对文件做一些修改,收集数组中的事件,然后从false返回watcherFunc,然后在数组上断言。当然,当goroutine开始时,测试只是挂起并等待事件。

有什么方法可以测试这样的函数,比如...启动一个更新/修改文件的不同线程(?)?

1 个答案:

答案 0 :(得分:0)

  

有什么方法可以测试这样的函数,比如...启动一个更新/修改文件的不同线程(?)?

当然......启动一个可以进行所需更新的goroutine。

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)
}