# RestHighLevelClient mocking

**URL:** <https://discuss.elastic.co/t/resthighlevelclient-mocking/123027>\
**Category:** Elasticsearch\
**Created:** [March 8, 2018, 9:06am UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027 "2018-03-08T09:06:51Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![infodavid](https://avatars.discourse-cdn.com/v4/letter/i/ea5d25/32.png) [@infodavid](https://discuss.elastic.co/u/infodavid)\
**Post date:** [March 8, 2018, 9:06am UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/1 "2018-03-08T09:06:52Z")

</div>

Hi,

Is there a way to mock the Java client 'RestHighLevelClient' ? Most of the methods are 'final' and can't be overridden.

Thanks for your support.

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [March 8, 2018, 11:03am UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/2 "2018-03-08T11:03:10Z")

</div>

I don't think you can do that.

À workaround would be to use the client from your own ElasticsearchDao class and mock this one instead.

Would that work?

---

<div class="post-metadata">

**Author:** ![infodavid](https://avatars.discourse-cdn.com/v4/letter/i/ea5d25/32.png) [@infodavid](https://discuss.elastic.co/u/infodavid)\
**Post date:** [March 8, 2018, 1:33pm UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/3 "2018-03-08T13:33:14Z")

</div>

Hi,

Thanks for the answer.  
We already have something similar to a DAO to request ES. THe goal is to test the DAO like behavior to detect issue and regressions.

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [March 8, 2018, 2:38pm UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/4 "2018-03-08T14:38:42Z")

</div>

I understand your point.

But the DAO is just a router to elasticsearch normally, no?  
Like it's doing something like (pseudo code):

```auto
public List<MyObject> search(String term) {
  SearchResponse response = esClient.search(new SearchRequest()...);
  return MyObject.fromJson(response.toString());
}

```

There should be barely no intelligence here IMO.  
Smart things should be done on a higher level like a Service layer.

Mocking this method is then straight-forward when you want to test your service.

Indeed you can not "unit test" your DAO by itself.  
But you can do IT with it if needed.

@javanna has may be more thoughts on that and if there is any plan to make those methods not final.

---

<div class="post-metadata">

**Author:** ![infodavid](https://avatars.discourse-cdn.com/v4/letter/i/ea5d25/32.png) [@infodavid](https://discuss.elastic.co/u/infodavid)\
**Post date:** [March 8, 2018, 8:34pm UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/5 "2018-03-08T20:34:23Z")

</div>

I'm not fully aligned with your, IMO DAOs can be validated by some unit tests (see DBUnit or similar). For sure, you can still detect some issues during integration tests but I prefer to see the issue before that stage.

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [March 8, 2018, 8:51pm UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/6 "2018-03-08T20:51:44Z")

</div>

It depends on what you call a test.

I mean that if you have a method like:

```auto
public void save(Entity e) {
  db.save(e);
}

```

IMO it's pretty much useless to test that this method actually saves something in a DB if you are mocking the DB.

It's like testing a getter or setter of a Java Bean. Does make a lot of sense to me to test that.

But if your class does something smarter like:

```auto
public void save(Entity e) {
  if (db.save(e)) {
   messageQ.send("OK");
  } else {
   messageQ.send("KO");
  }
}

```

Then that's another story and in that case I would not consider that class as a DAO but as a Service.

I'd love to see what your DAO is doing actually what a typical unit test would look like. Could you share some example?

---

<div class="post-metadata">

**Author:** ![infodavid](https://avatars.discourse-cdn.com/v4/letter/i/ea5d25/32.png) [@infodavid](https://discuss.elastic.co/u/infodavid)\
**Post date:** [March 9, 2018, 7:07am UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/7 "2018-03-09T07:07:19Z")

</div>

Hi,

You point your finger on the right topic. Sometimes DAO make transformations, aggregations or else and it can be a good practice to validate the query. For sure it depends on the project and that's an other discussion.

In our case, we make some transformations.

Thanks for your help

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [March 9, 2018, 5:01pm UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/8 "2018-03-09T17:01:51Z")

</div>

> Sometimes DAO make transformations, aggregations or else and it can be a good practice to validate the query.

Yeah. But let say you implement something like this:

```auto
class MyDao {
  public SearchResponse search(SearchRequest request) {
    return esClient.search(request);
  }

  public SearchRequest buildRequest(QueryBuilder query) {
    return new SearchRequest("person").source(new SearchSourceBuilder()
                                  .query(query)
                                  .aggregation(/* whatever */));
  }
}

```

Then what you actually want to test is the `buildRequest()` method right?  
Not the fact that this method can be executed correctly against a fake `esClient` which you wanted to mock, right?

That's only my personal opinion here. Again, I'd like to see what you wrote if you don't mind sharing it as I might be totally wrong with your use case.

---

<div class="post-metadata">

**Author:** ![infodavid](https://avatars.discourse-cdn.com/v4/letter/i/ea5d25/32.png) [@infodavid](https://discuss.elastic.co/u/infodavid)\
**Post date:** [March 9, 2018, 5:35pm UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/9 "2018-03-09T17:35:25Z")

</div>

Not exactly. Our DAO doesn't expose es objects. It's in charge of building the query and then the request by using some data from our model and logic. But the goal of this topic is not to discuss the conception of our indexing layer, just to get a way to implement unit tests without having an es installed.

---

<div class="post-metadata">

**Author:** ![RishuK](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rishuk/32/28529_2.png) [@RishuK](https://discuss.elastic.co/u/RishuK)\
**Post date:** [March 16, 2018, 1:51pm UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/10 "2018-03-16T13:51:47Z")

</div>

Hi,

Even a simple thing as below does not seem to be working when I am trying to test my Service class which is using RestHighLevelClient.index() method.

It internally calls performRequest which gives a null pointer exception. Any ideas how to achieve this?

```
IndexResponse indexResponse = Mockito.spy(new IndexResponse(new ShardId(new Index("test", "test-uuid"), 1), "testmapping", "1", 1, true));
        indexResponse.setShardInfo(new ReplicationResponse.ShardInfo());
        indexResponse.setForcedRefresh(true);

        Mockito.doReturn(indexResponse).when(restHighLevelClient).index(any());
```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [May 3, 2018, 8:13pm UTC](https://discuss.elastic.co/t/resthighlevelclient-mocking/123027/12 "2018-05-03T20:13:32Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
