如何验证在单独的go例程中调用方法

时间:2017-11-24 05:36:51

标签: unit-testing go testify

在为go中的方法编写单元测试时,我很难解决问题。首先,测试中的代码片段:

func MehodToBeTested(e Entity) {
  go saveAudit(e)

 //do something on which assertions can be done
}

实体可以被嘲笑。在saveAudit方法中,调用Entity.Save方法。在我的UT中,我想断言Entity.Save方法被调用一次。以下是我目前的UT:

func TestMethod(t *testing.T) {
  var mock = &mockEntity{}
  mock.On("Save").Return(nil)

  //make call to func under test
  MethodToBeTested(mock)

  // Assert that Save is called on Entity
  mock.AssertNumberOfCalls(t, "Save",1)
}

这是错误的说法:预期的呼叫数(1)与实际呼叫数(0)不匹配,因为实际呼叫是在另一个例行程序中发生的。我该如何测试?

2 个答案:

答案 0 :(得分:2)

我使用相同的技术。等待goroutine结束。很可能还没有确定。

另外,我建议使用竞争条件检测器进行此类测试。它有助于捕捉这种情况。然后,您可以向测试添加一些同步以使其可靠。

我的测试示例。经过测试的函数应并行检查两个网页是否包含指定的字符串。因此,测试应检查测试功能是否已访问过两个页面

更新:附加了错误的测试。固定。

func TestCheckSites_TwoSlowHandlers_BothContain(t *testing.T) {
    var config = GetConfig()
    var v1, v2 bool
    var wg sync.WaitGroup
    wg.Add(2)
    handler1 := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        defer wg.Done()
        v1 = true
        time.Sleep(2 * config.Http.Timeout) // Use double HTTP_TIMEOUT
        io.WriteString(w, "Present")
    })
    ts1 := httptest.NewServer(handler1)
    defer ts1.Close()

    handler2 := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        defer wg.Done()
        v2 = true
        time.Sleep(2 * config.Http.Timeout)
        io.WriteString(w, "Present")
    })
    ts2 := httptest.NewServer(handler2)
    defer ts2.Close()

    result, err := checkSites([]string{ts1.URL, ts2.URL}, "Present")
    assert.Equal(t, nil, err, "Error should be nil")
    assert.Contains(t, []string{""}, result, "Should be empty string")
    //assert.(t, ts1.URL, result, "Should first or second empty string")
    wg.Wait()
    assert.Equal(t, true, v1, "First server should be visited")
    assert.Equal(t, true, v2, "Second server should be visited")
}

答案 1 :(得分:0)

@Flimzy在这里写这是因为注释不能包含漂亮的代码示例。希望没事。考虑以下情况(愚蠢,但出于示例考虑):

type MyStruct struct {
    counter int
}

func (s *MyStruct) Add(item string) {
    s.ConfirmAdd()
}

func (s *MyStruct) ConfirmAdd() {
    s.counter++
}

ConfirmAdd()的测试可能如下

func TestConfirmAdd(t *testing.T) {
    s := MyStruct{}
    s.ConfirmAdd()
    Assert(s.counter, Equals, 1)
}

Add()编写测试时,您什么都不会写吗?很难断言没有ConfirmAdd()被呼叫。