2

I'd like to make sure that we're starting a goroutine by calling a function with the right arguments.

For example:

func MyTest(t *testing.T) {
    service.EXPECT().MyMockFunc(1)
    service.MyFunc()
}

func MyFunc() {
    go MyMockFunc(1)
}

When I run this test, it fails because (I believe) MyMockFunc only gets called after the test has already finished running.

Is there a way to test that I started a goroutine by calling a function with the right arguments?

Note: Ideally, I'd like to keep the arguments I pass to MyMockFunc as is (not add a channel arg for instance).

yndolok
  • 5,197
  • 2
  • 42
  • 46
  • 2
    you can't be sure a goroutine runs or returns at all without synchronization. You need to add a channel or WaitGroup to ensure that. – JimB May 26 '18 at 01:04
  • 2
    Don't test that a goroutine was started. Test that a goroutine did what it was supposed to. Assert its effects, not its existence. – Peter May 26 '18 at 07:14
  • Have the same problem. time.Sleep(time.Millisecond) - works but I think it's not our way :) – Kostya Vyrodov Oct 01 '18 at 14:59

1 Answers1

-1

Using a channel and assuming you can fire the goroutine from the test:

package main

import (
    "fmt"
    "testing"
    "time"
)

func MyMockFunc(n int) int {
    fmt.Println("MyMockFunc is called")
    time.Sleep(5 * time.Second)
    return n + 1
}

func TestMyMockFunc(t *testing.T) {
    result := make(chan int)
    go func() {
        result <- MyMockFunc(1)
    }()
    if <-result != 2 {
        t.Fatalf("Expecting 2")
    }
}
Matías Insaurralde
  • 1,202
  • 10
  • 23