mardi 10 avril 2018

import cycle for mocked object in test case

I have a package root_package with the following types:

type User struct {}
type Service struct { iclient }
type iclient interface {
    GetUser(id string) *User
}
// client struct that implements iclient with http.Client
// NewService that returns Service with embedded client

Service is the type that outsiders will be using, they are only allowed to create it using the NewService function which connects to a HTTP server. It automatically exposes the methods from the unexposed iclient.

So far so good, however, I'm mocking an iclient to run some unit tests without hitting the network. I put these mocked files inside a mocks directory. However, when referencing both Service and mocks.Client (which in turn references root_package.User as it needs to return that) from the test case which is in root_package, I get an import cycle.

Now, there are some ways I can resolve this:

  • put the Client mock in the same package. However, this exposes it to consumers which I don't want. I could put it in the _test file (can I?) to not expose it, however, I like to separate them as the mock file can become very large.
  • put the test in a separate package root_package_test. However, this way, I cannot create a Service with the unexposed iclient without also allowing outsiders to do the same (which may break integrity of the package etc.)
  • Put the *User struct in a separate root_package_types package (so the mocks.Client doesn't reference the root_package anymore. However, this adds a new otherwise unnecessary package and a whole new layer of complexity to the library.

What is the best way to approach this?

Aucun commentaire:

Enregistrer un commentaire