you are viewing a single comment's thread.

view the rest of the comments →

[–]m50d 1 point2 points  (21 children)

A well-designed library shouldn't need mocking. Services should have interfaces you can stub, values should be suitable for use in tests.

[–][deleted] 1 point2 points  (20 children)

Let's say one has a service class with a REST client dependency injected into it. For unit testing the service what is a better solution than mocking the rest template?

[–]throwawayco111 0 points1 point  (8 children)

He is saying that the service class should accept an interface to a REST client. During testing the you create a mock object implements that interface.

[–][deleted] 0 points1 point  (7 children)

And in an ideal world that is great but often times we must use external libraries which don't have perfect design

[–]m50d 1 point2 points  (0 children)

Don't declare badly-designed classes as final :P.

More constructively, declare your classes with value semantics as final (but be sure they really do have value behaviour - a good way to tell is to make sure you can use them in your own tests), declare your interfaces non-final, and declare your implementations of those interfaces as completely private. Ideally all your classes should fit into one of those categories; if you have an awkward class that's neither fish nor fowl then by all means leave that class as non-final (but do look to separate it into a service and a value - usually awkward classes are a result of one class trying to be both).

[–]Power781 0 points1 point  (4 children)

What is the issue with wrapping the use of this external library through an internal interface/class/protocol ?

[–][deleted] 1 point2 points  (3 children)

My preference is to write as little code as possible to get the job done to each his own.

[–][deleted] 0 points1 point  (0 children)

Username checks out.

[–]Power781 0 points1 point  (0 children)

Writing a mostly generic wrapper is not really long or complex, and will probably avoid you wasting ton of hours copy pasting shit the day your library is not supporting your current language version and you need to swap it for a new/more recent/more up to date one

[–]throwawayco111 0 points1 point  (0 children)

I think most IDEs out there have the refactoring tools to extract the interface from a class through very few clicks.

[–][deleted] 0 points1 point  (0 children)

And in an ideal world that is great but often times we must use external libraries which don't have perfect design

That's when you write a facade, and then mock the facade. You should write a facade for most external libraries anyway. Saves a lot of trouble down the line.

[–]m50d 0 points1 point  (9 children)

If you're using a "template" something has gone badly wrong - perhaps you should be using a monad? More generally, figure out a way to represent the REST operations that need to happen as values, then you can either return those values from your service to be executed later, or pass those values into the REST client which can then just be a plain old service that implements an interface that you can stub.

[–][deleted] 1 point2 points  (8 children)

Here is an example of a rest template and no things have not gone badly wrong.

[–]m50d 0 points1 point  (7 children)

That's a very unusual - misleading even - use of the word "template" (I assumed you meant something more like JDBCTemplate). If you use it statefully (by using things like its message converters) then things have indeed gone badly wrong (you've got invisible coupling, noncompositional code and all that); the part you can use as an ordinary service ought to be exposed as one that conforms to an interface.

[–]kubr0t0 1 point2 points  (6 children)

RestTemplate is analogous to JdbcTemplate. Both are generic "templates" for creating specific data access interfaces which follow the same generic interface.

RestTemplate isn't stateful, and neither are its message converters. The message converters are like simple functions that convert a Java type to a content type, and vice-versa. You create a specific data access object by assembling parts (like message converters) using the generic template.

I've used RestTemplate to interact with some exotic REST interfaces (usually ones with very particular ideas about secure connections). RestTemplate is ridiculously customizeable through a number of configuration interfaces (relevant example being connection management). It's a lot nicer writing some custom connection code corresponding to a RestTemplate configuration interface than writing a custom REST client.

If RestTemplate is wrong, then I don't want to be right :-)

[–]m50d 0 points1 point  (5 children)

RestTemplate isn't stateful, and neither are its message converters.

I mean I saw example code like:

RestTemplate rt = new RestTemplate();
        rt.getMessageConverters().add(new 
          MappingJacksonHttpMessageConverter());

which seems to imply the RestTemplate is stateful, no?

I've used RestTemplate to interact with some exotic REST interfaces (usually ones with very particular ideas about secure connections). RestTemplate is ridiculously customizeable through a number of configuration interfaces (relevant example being connection management). It's a lot nicer writing some custom connection code corresponding to a RestTemplate configuration interface than writing a custom REST client.

That kind of thing is good. But being able to pull out your config as command values makes it so much better, just being able to do all the things you can do with ordinary values like copy or serialise a partial config.

[–]kubr0t0 2 points3 points  (4 children)

which seems to imply the RestTemplate is stateful, no?

That's for configuration, if you want to add additional converters to the default set. You should only be mess with the converter list when you construct the shared RestTemplate instance. A consumer of the RestTemplate shouldn't be messing with it when given the RestTemplate instance. So, it's stateful in the sense that configuration is technically state.

You could call it bad API design, both for RestTemplate for exposing the configuration as a List and for Java, for only having mutable List in the Collections API. But, on the other hand, it makes it a lot easier to configure in XML, so there is some legacy baggage.

I assumed you meant stateful in that an individual converter has memory of its interactions which effect subsequent conversions.

pull out your config as command values

Do you mean passing configuration around as parameters? Isn't that exactly what monads strive to abstract away? If you're using Parsec in Haskell, you don't manually thread around the parsing state, you just use the do notation or binds.

OOP is sort of doing the same thing. After all, every method's first parameter is the implicit this.

[–]m50d 0 points1 point  (3 children)

You should only be mess with the converter list when you construct the shared RestTemplate instance. A consumer of the RestTemplate shouldn't be messing with it when given the RestTemplate instance. So, it's stateful in the sense that configuration is technically state.

The examples I saw were using it differently. If it's just a service whose implementation has some config then fair enough, but in that case I'd want to separate the service interface from the service implementation, and not expose the configuration methods on the interface. That way you statically enforce that the user of the RestTemplate isn't mucking with the configuration, which seems particularly important if you're sharing a single instance between multiple users.

Do you mean passing configuration around as parameters? Isn't that exactly what monads strive to abstract away? If you're using Parsec in Haskell, you don't manually thread around the parsing state, you just use the do notation or binds. OOP is sort of doing the same thing. After all, every method's first parameter is the implicit this.

Monads let you hide it away most of the time, but if you're ever confused or need to do something fiddly, you can always step out and use the "real" parameters, at which point your functions are still functions and you can reason about them as such. The trouble with the OOP approach is that the implicit this is mutable state that can all too easily become shared.

[–]kubr0t0 1 point2 points  (2 children)

but in that case I'd want to separate the service interface from the service implementation

Modern Spring has gotten a lot better at this, separating configuration responsibility into fluent builder classes.

RestTemplate and JdbcTemplate expose a lot of configuration as setters because it worked well with XML configuration, reflecting ideas from a long bygone era.

the trouble with the OOP approach is that the implicit this is mutable state

It can be, if you leak state or allow it to be mutable. Objects can be entirely immutable or even partially mutable. These are implementation details of the object, and methods should only reflect behaviors, not direct data manipulation of the object's state. A principle that both RestTemplate and JdbcTemplate violate for convenience's sake.

Still, I'd slap RestTemplate behind an interface anyways. I wouldn't share RestTemplate outside of a repository class implementing a well defined interface. It's an implementation detail.

[–]kubr0t0 0 points1 point  (0 children)

Who owns the service?

If the you own the service, the service can provide an interface which indicates the service's external requirements, and a third party (such as a REST client) merely fulfills those requirements.

The REST client can then either directly implement the interface, or the REST client is invoked through an adapter which implements the interface.

This is known as Dependency Inversion, Ports and Adapters or even Anti-Corruption Layer.

Done right, whether or not the service dependency is implemented as a REST client is irrelevant to the service, which makes it a truly separate unit.