Support mock some stdlib functions
Some use case involve mocking time.Now,time.Sleep, etc.
For example: https://www.reddit.com/r/golang/s/VKGwG7SjlG
Currently IR rewritting is turned off for stdlib. Should add support for these functions and may even allow user to specify what other functions they want to mock.
So up to now, xgo cannot be patched for any standard library functions?
Stdlib is no difference with user written lib.It's just that currently stdlib is skipped by default.Will explore a way for user to control whether stdlib should be trapped.
Mock stdlib functions will be useful in test
@WAY29 I'm planning to enable mock by default for these stdlib functions, how do you think?
time.Now
time.Sleep
os.Getenv
net/http.*
Do you think we need to add more?
@WAY29 I'm planning to enable mock by default for these stdlib functions, how do you think?
time.Now time.Sleep os.Getenv net/http.*Do you think we need to add more?
Maybe add a cmd option is better?
@WAY29 I'm planning to enable mock by default for these stdlib functions, how do you think?
time.Now time.Sleep os.Getenv net/http.*Do you think we need to add more?
Maybe add a cmd option is better?
Ok, I will add support for it. Currently, what stdlib function do you want to mock?
@WAY29 I'm planning to enable mock by default for these stdlib functions, how do you think?
time.Now time.Sleep os.Getenv net/http.*Do you think we need to add more?
Maybe add a cmd option is better?
Ok, I will add support for it. Currently, what stdlib function do you want to mock?
net.*
However I think udp connection is unable to mock, because it's a struct pointer but not a interface... There is no good way
This is still working because it seems that standard lib is a little different from ordinary code. The IR rewriting is not taking effect.I'm solving it using source rewriting.
@WAY29 mocking stdlib functions has been supported, see commit https://github.com/xhd2015/xgo/commit/f911dc86a2f7dbb62b2361f3649c823e0b2ea4b8
As usual, you may need to upgrade xgo and go get github.com/xhd2015/xgo/runtime@latest to use the latest version.
Here is an example mocking time.Now:
package mock_time_now
import (
"context"
"testing"
"time"
"github.com/xhd2015/xgo/runtime/core"
"github.com/xhd2015/xgo/runtime/mock"
)
func TestMockTimeNow(t *testing.T) {
now1 := time.Now()
now2 := time.Now()
d1 := now2.Sub(now1)
if d1 <= 0 {
t.Fatalf("expect now2-now1 > 0 , actual: %v", d1)
}
cancel := mock.Mock(time.Now, func(ctx context.Context, fn *core.FuncInfo, args, results core.Object) error {
results.GetFieldIndex(0).Set(now1)
return nil
})
now3 := time.Now()
if now3 != now1 {
t.Fatalf("expect now3 equals to now1 exactly, actual diff: %v", now3.Sub(now1))
}
cancel()
now4 := time.Now()
d4 := now4.Sub(now1)
if d4 <= 0 {
t.Fatalf("expect now4-now1 > 0 after cancelling mock, actual: %v", d4)
}
}
Another example mocking http.Client.Do:
package mock_http_do
import (
"context"
"net/http"
"testing"
"github.com/xhd2015/xgo/runtime/core"
"github.com/xhd2015/xgo/runtime/mock"
)
func TestMockHTTP(t *testing.T) {
var haveMocked bool
mock.Mock(http.DefaultClient.Do, func(ctx context.Context, fn *core.FuncInfo, args, results core.Object) error {
haveMocked = true
return nil
})
http.DefaultClient.Do(nil)
if !haveMocked {
t.Fatalf("expect http.DefaultClient.Do to have been mocked, actually not mocked")
}
}
However, there are limitations on mocking stdlib functions. Currently only a list of packages and functions can be mocked, you can view them at runtime/mock/stdlib.md.
Of course, if there are some functions you want to mock are missing, you can leave a comment here, I'll test then and then add them.