gresrun / jesque

An implementation of Resque in Java.

Home Page:http://gresrun.github.io/jesque

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ehance testability of clients

deanhillertwitter opened this issue · comments

cool library with some interesting ideas.

Ideally, I was trying to create a simple wrapper to hide jesque(and simulate jesque) from a testability perspective. Unfortunately, the design seems to be preventing that or I am missing a method I could use? Perhaps you might know?

I was trying to create a singleton like so

public class ResqueWrapper {

public void addQueueListener(ResqueListener l, Collection<String> queueNames) {
  //VERY VERY little code that I can only test in staging
}

public void remoteQueueListener(ResqueListener l) {
}

}

As I got into implementing this, I found out jesque is doing some reflection stuff that I would like to avoid especialy since it is on my business logic and I prefer to have all business logic stateless and created via guice. I really just want jesque to call

resqueListener.processItemsInQueue(String fromQueue, Items items)
resqueListener.failed(fromQueue, Throwable t)

where Items has an ack or nack. Then I can fully simulate my system. Unfortunately, jesque is making it really hard to wrap my system in a 'large' system type test where I swap out guice remote endpoints(so it's all single threaded and doesn't talk remotely at all during the test). This enables us to test talking to S3 failures after getting a resque item and make sure the system does what it is supposed to on an S3 failure or an mysql failure, etc. etc.

Is there any way to do this?

For one thing, the reflection to create a job class is what is hurting me. Reflection to create a data object to pass into a generic resque listener would have been ok like ResqueListener

Ideally, the api should only be passing data rather than fiddling with my business logic such that my test can easily do the same. It just creates a situation in which the test can simulate 99% of the code rather than 70% of the code which is what we have right now.

It's hard to explain this concept, but basically our tests on other projects do this

  1. feed in data through to the listener(test has a reference to the listener as it mocks the ResqueWrapper to be able to grab the listeners that were added)
  2. from there it is 100% production code until the remote endpoint
  3. at the remote endpoint, our test throws an exception
  4. then we verify a call to mysql results in recording that exception as well(which again is a mocked endpoint).

thanks,
Dean

@deanhillertwitter, I'm not following your question.

About the reflection, you can write your own JobFactory implementation. The default/provided ones use reflection but the constructor to WorkerImpl takes any instance of JobFactory.

I don't understand how your ResqueWrapper and ResqueListener interact with Jesque.
Also, are you trying to mock out the network calls in your tests?

We ended up putting a hack in. (this is my other account). Ideally though if there was an api that we just added a listener to, we would mock that and the test would grab the listener and feed resque events into the system all without mocking network calls.

Instead, we have a hack in place such that we can test our code better. It is not that clean and I don't see a clean way of doing it.

we write very high level tests mocking every remote system and 3rd party library. mocking jesque was rather difficult and is still not really there so we ended with a hack.

In an ideal system, we would just receive the object off the queue to some listener we added to jesque. something like that is much easier to mock is all.