elasticsearch-php icon indicating copy to clipboard operation
elasticsearch-php copied to clipboard

Client should implement an interface to make unittesting possible.

Open davidmaes opened this issue 3 years ago • 2 comments

Summary of problem or feature request

Since client was made final we can not mock the class anymore. However, good practice would tell us that we need to mock the edges of our systems. Of course ES is such an edge.

Therefore, whenever important classes like this are made final, an interface should be created to help us mock that instead. Of course it also helps us think about the system through an interface instead of an implementation.

I assume there are more people running into this problem so I have a pull request ready to go.

davidmaes avatar Jun 02 '22 12:06 davidmaes

I agree. Another solution would be to simply remove final. Sure, it makes sense to not extend the client but the hassle it creates with testing makes it simply not worth adding the keyword.

Ekman avatar Jun 09 '22 13:06 Ekman

Do we have any updates here? the implementation of #1228 is good but the problem here is the traits generated by a script. So, in my opinion, that generator needs to create interfaces automatically per trait, and the client interface needs to extend these interfaces. @ezimuel what do you think? We struggled in this library also to be able to test some parts after upgrading to the latest version.

hkulekci avatar Jun 12 '22 18:06 hkulekci

@davidmaes, @Ekman , @hkulekci first of all I'm sorry for the long wait. You are right, we need to provide an Interface to be sure that we can mock the Client easily. As pointed out by @hkulekci this interface should be generated, since the Client used some generated code (i.e. ClientEndpointsTrait. I'm working on a PR for that. Thanks!

ezimuel avatar Aug 18 '22 08:08 ezimuel

Since I need to generate the interface based on the API endpoints released in Elasticsearch I can have different interfaces between two minor versions. This can be a BC break! I'm considering to remove the final keyword for the Client. Thoughts?

ezimuel avatar Aug 18 '22 11:08 ezimuel

What do you think about creating an interface for the Client method instead of all functions only? The libraries can mock the sendRequest method easily. This is a quick opinion. I did not think about it much :)

hkulekci avatar Aug 18 '22 12:08 hkulekci

@hkulekci Do you mean an interface only for the Client methods without the ClientEndpointsTrait and NamespaceTrait? It sounds a great idea! Any thoughts @davidmaes and @Ekman ?

ezimuel avatar Aug 18 '22 12:08 ezimuel

Yes exactly. As I see from my limited view, all the public methods which are sending a request to Elasticsearch use sendRequest method as well. So, mocking this request will be a solution. For the NamespaceTrait, the classes are using AbstractEndpoint and this class depends on Client. All the methods of these classes also use the same method of Client.

hkulekci avatar Aug 18 '22 13:08 hkulekci

Mocking sendRequest would mean users needs to concern themselves with internal lib stuff in order to mock. I mean, it works, but it's not ideal. I'd prefer removing final or an interface but I also understand implementing simpler solutions over more complex. 🙂

Ekman avatar Aug 18 '22 14:08 Ekman

@hkulekci , @Ekman I just sent this PR #1249

ezimuel avatar Aug 23 '22 14:08 ezimuel

I put a comment there. Thanks 🥳

hkulekci avatar Aug 23 '22 17:08 hkulekci

Solved in https://github.com/elastic/elasticsearch-php/pull/1249. Thanks @hkulekci for the suggestion!

ezimuel avatar Aug 24 '22 06:08 ezimuel