go-faker / faker

Go (Golang) Fake Data Generator for Struct, previously https://github.com/bxcodec/faker
https://pkg.go.dev/github.com/go-faker/faker/v4
MIT License
614 stars 30 forks source link

CustomProvider only supports tagged fields #7

Open xxxserxxx opened 1 year ago

xxxserxxx commented 1 year ago

Custom providers are not called for public, untagged fields.

type A {
   B string
}
func main() {
  faker.AddProvider("B", func(v reflect.Value) (interface{}, error) {
    return "XYZ", nil
  }
  var a A
  faker.FakeData(&a)
  if a.B != "XYZ" {
    panic("expected XYZ, got "+a.B)
  }
}
bxcodec commented 1 year ago

This is expected. The custom providers only support tagged fields. We can't check based on struct's property yet.

xxxserxxx commented 1 year ago

Is there a way to provide data through faker for structures imported from an external dependency, or is it restricted to only structures that are local to the package?

bxcodec commented 1 year ago

What do you mean? is it something like you mention above?

Or do you have any some usecase?

xxxserxxx commented 1 year ago

Sure! For example, say I have this code:

import "runtime"
type MyThing struct {
  runtime.BlockProfileRecord
}
func (m MyThing) Agg() int {
  return m.Count * m.Cycles
}
func (m MyThing) HorribleHash() int {
  var hash int
  for _, k := range m.Stack0 {
    hash += k % 4294967295
  }
  return hash
}

and I'd like to test that Agg() and HorribleHash() work correctly. This is a trivial case; they can be tested entirely outside of faker, by using table driven tests or similar. Or, one could re-implement the functions' logic in the tests and verify randomly-generated faked data. There are cases, however, where we'd like to control the data, and supply a Provider.

However, as you say, Provider will not work here, because the BlockProfileRecord fields are not tagged and can't be tagged, because the source code is external to the project.

This is going to be the situation for any code that uses structures defined by an external library. We may want to test the code, but we can't tag the structures the code uses. When we can test using randomized data, this isn't an issue, but how do we handle cases where we would like to have a Provider for externally-defined structures?

bxcodec commented 1 year ago

I'll try to look into this in more detail. I can't promise much, it might be possible or it might not. If you have any documents or references that could help, please help to post them here. It will be great if we can support this!!!

xxxserxxx commented 1 year ago

I haven't looked through the code; are you using introspection to get at record fields? It's straightforward to get the public fields fields through reflect. Supporting providers for exported fields, regardless of marshelling tags, would be the least surprising for users, I think.