[
https://issues.apache.org/jira/browse/TINKERPOP-1756?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16141503#comment-16141503
]
stephen mallette commented on TINKERPOP-1756:
---------------------------------------------
ok - so you're using {{withRemote()}}. I don't think mocking {{Cluster}} and
{{Client}} and other low-level objects is "nice". I've had to do it before for
"simple" things and it's not fun. I also don't know that it would be good for
this use case. the higher up the chain a mock is the closer you are to testing
the code you want to test. While I could just make {{Cluster}} non-final so
that you could do this, I'd rather come up with a better solution for easier
mocking for everyone because {{withRemote()}} will be an often used capability
and the demand for mocking will be there. So, perhaps we can work out a better
solution together?
My initial thought was to just mock the {{RemoteConnection}} interface. I
pictured people doing that for this use case when we designed {{withRemote()}}.
that interface is also purposely simple because we want driver providers to
implement it. If you mock {{RemoteConnection}} you completely bypass all the
internals of {{Cluster}} and you only have to mock a single method which is
much more clean:
{code}
public <E> RemoteTraversal<?, E> submit(Bytecode bytecode) throws
RemoteConnectionException
{code}
The nice part about introducing the mock here is that you just need to return a
{{RemoteTraversal}} which is an extension of {{Traversal}} itself. Why is that
good? Because you can execute the bytecode against a local graph instance like
TinkerGraph (or even the actual graph you are using if you can get an embedded
instance of it) and then wrap it in a {{RemoteTraversal}} and your unit test
case is complete. Of course, what I'm finding is that implementing
{{RemoteTraversal}} is currently annoying for a "simple" mock. There are a lot
of methods, many of which probably go unused for the {{withRemote()}} use case.
I'm thinking about adding an {{InProcessRemoteTraversal}} class that basically
will act as a default implementation for {{RemoteTraversal}} which can either
work out of the box in the way I just described or act as a base class for
extension if needed. In this way, the implementation of mock of
{{RemoteConnection}} would just be:
{code}
@Test
public void testMock() throws Exception {
final TinkerGraph remoteGraphToTest = TinkerFactory.createModern();
final GraphTraversalSource remoteGToTest =
remoteGraphToTest.traversal();
Graph graph = EmptyGraph.instance();
GraphTraversalSource g = graph.traversal().withRemote(new
RemoteConnection() {
@Override
public <E> Iterator<Traverser.Admin<E>> submit(Traversal<?, E>
traversal) throws RemoteConnectionException {
return null;
}
@Override
public <E> RemoteTraversal<?, E> submit(Bytecode bytecode) throws
RemoteConnectionException {
return new
InProcessRemoteTraversal(JavaTranslator.of(remoteGToTest).translate(bytecode));
}
@Override
public void close() throws Exception {
}
});
assertEquals(6L, g.V().count().next().longValue());
}
{code}
That test passes with some junky code I wrote so the concept is sound. in fact
I could also make an {{InProcessRemoteConnection}} so you can just supply that
to your {{withRemote()}} method and avoid having to mock all together:
{code}
g = graph.traversal().withRemote(new InProcessRemoteConnection(remoteGToTest));
{code}
That seems like an easy way to go without forcing folks to mock really complex
classes like {{Cluster}}. What do you think?
> I wish Cluster was an interface so that I could mock it
> -------------------------------------------------------
>
> Key: TINKERPOP-1756
> URL: https://issues.apache.org/jira/browse/TINKERPOP-1756
> Project: TinkerPop
> Issue Type: Improvement
> Components: driver
> Affects Versions: 3.2.4
> Reporter: Anish Doshi
>
> {{org.apache.tinkerpop.gremlin.driver.Cluster}} is currently a final class.
> Which means that every time I need to mock this class, I cannot. I have to
> create a separate object and mock that object instead of mocking {{Cluster}}.
> Is there a chance that Cluster can be changed to an interface, or at least
> not have as a {{final}} class?
> Thanks.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)