title: How do you override Play framework controller in a unit testing context?
body: <p>I am creating a basic POST JSON api endoint. I would like to unit test it, and want to make sure I am doing it appropriately in the Play framework. So far I am using Guice for dependency injection and JUnit for my unit testing library.</p>
  
  <p>Here is my controller code:</p>
  
  <pre><code>public class NotificationController extends Controller {
  
    private RabbitQueueService _rabbitQueueService;
  
    @Inject
    public NotificationController(RabbitQueueService service) {
      _rabbitQueueService = service;
    }
  
    @BodyParser.Of(BodyParser.Json.class)
    public Result post() {
      ObjectMapper mapper = new ObjectMapper();
      Notification notification;
  
      try {
        JsonNode notificationJsonNode = Controller.request().body().asJson();
        notification = mapper.readValue(notificationJsonNode.toString(), 
                                        Notification.class);
        _rabbitQueueService.push(notification);
        return Results.created(notificationJsonNode, "UTF-8");
  
      } catch (JsonParseException e) {
        e.printStackTrace();
      } catch (JsonMappingException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
  
      return Results.badRequest();
    }
  }
  </code></pre>
  
  <p>My RabbitQueueService code:</p>
  
  <pre><code>public class RabbitQueueService {
  
    private Channel _channel;
    private Connection _connection;
  
    public RabbitQueueService() {
        ConnectionFactory factory = new ConnectionFactory();
      factory.setHost(Config.RABBITMQ_HOST);
      try {
        _connection = factory.newConnection();
        _channel = _connection.createChannel();
        _channel.queueDeclare(Config.RABBITMQ_QUEUE, false, false, false, null);
        _channel.exchangeDeclare(Config.RABBITMQ_EXCHANGE, "fanout");
        _channel.queueBind(Config.RABBITMQ_QUEUE, Config.RABBITMQ_EXCHANGE, "");
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    public void push(Notification notification) {
      try {
        _channel.basicPublish(Config.RABBITMQ_EXCHANGE, "", null, notification.getBytes());
          _channel.close();
          _connection.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  
    public void pop() {
  
    }
  }
  </code></pre>
  
  <p>My MockQueueService code:</p>
  
  <pre><code>public class MockQueueService extends RabbitQueueService {
  
    @Override
    public void push(Notification notification) {
      /* Do nothing because you know... thats what I do */
    }
  
    @Override
    public void pop() {
      /* Do nothing because you know... thats what I do */
    }
  }
  </code></pre>
  
  <p>and finally my current unit test code:</p>
  
  <pre><code>public class ApplicationTest {
  
      @Test
      public void addMessageToQueue() {
        running(fakeApplication(), new Runnable() {
            public void run() {
                FakeRequest request = new FakeRequest("/POST", "/api/v1/notifications");
                Notification notification = new Notification(UUID.randomUUID(), 
                                                             new NotificationType(UUID.randomUUID(), 
                                                                                  "Critical"), 
                                                             "Test notification message");
          try {
                    ObjectMapper mapper = new ObjectMapper();
                    String json = mapper.writeValueAsString(notification);
                    JsonNode node;
            node = mapper.readTree(json);
                    request.withJsonBody(node);
          } catch (IOException e) {
            e.printStackTrace();
          }
                route(request);
            }
          });
      }
  }
  </code></pre>
  
  <p>This all works fine when making a curl request to test my endpoint through play run. My main question is: how do I use the MockQueueService in my unit test? I don't see anyway to do it with fakeApplication() helper. I could instantiate it directly like</p>
  
  <pre><code>NotificationController nc = new NotificationController(new MockQueueService());
  nc.post();
  </code></pre>
  
  <p>but the problem is I need to override the body of the play request with an appropriate request body and I <strong>think</strong> I need a FakeRequest for that.</p>
  
  <p>Any help, samples, or advice would be helpful.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I have posted a <a href="https://gist.github.com/elaforc/9105687" rel="nofollow">gist example</a> with the necessary example files. The things specifically that I did to get it working:</p>
  
  <ul>
  <li>Setup a new GlobalUnitTest file that I passed into the fakeApplication helper</li>
  <li>Changed NotificationController to be a singleton. This allowed me to pull in the NotificationController instance so I could check the QueueService count as part of the assertion.</li>
  </ul>