9

I built my Retrofit instance like this:

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(server.url("/"))
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .build();

Then I am calling my MockWebServer instance like this:

server.enqueue(new MockResponse().setBody(jsonStr));

Where jsonStr is built like this:

MyModel model = new MyModel("HOME", "AWAY", "ENTERTAIN", "NIGHT", "MUTE",
            "VOLUME", "SCENE 1", "SCENE 2", "SCENE 3");
JsonAdapter<MyModel> jsonAdapter = moshi.adapter(MyModel.class).toJson(model);

However, the code crashes at this point:

Response response = api.getString().execute();

The exception is:

com.squareup.moshi.JsonDataException: Expected a string but was BEGIN_OBJECT at path $

What did I do wrong?

IgorGanapolsky
  • 26,189
  • 23
  • 116
  • 147

3 Answers3

17

I found the solution: My api interface needed to have

@GET("/") Call<JsonObject> getString();

NOT

@GET("/") Call<String> getString();

The reason is that I am mocking a JSON response, not a plain String.

Salvatore Testa
  • 317
  • 2
  • 9
IgorGanapolsky
  • 26,189
  • 23
  • 116
  • 147
6

In my case, when my codes are as the following, i get the same error mentioned in the question.

com.squareup.moshi.JsonDataException: Expected BEGIN_OBJECT but was STRING at path $.elections[0].ocdDivisionId

private val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .add(DateAdapter())
    .add(ElectionAdapter())
    .build()

The problem is related to ElectionAdapter.

After changing the order of adding adapters, namely putting .add(ElectionAdapter()) at the top as show below, the problem is solved :

private val moshi = Moshi.Builder()
    .add(ElectionAdapter())
    .add(KotlinJsonAdapterFactory())
    .add(DateAdapter())
    .build()
oiyio
  • 5,219
  • 4
  • 42
  • 54
6

For my case I omitted the ScalarsConverterFactory for parsing the JSONString

You see my API Call was supposed to return a JSON String

` @GET("neo/rest/v1/feed")
     suspend fun getNearEarthObjects(@Query("api_key") apiKey: String): String`

When building the Retrofit Object I had the Moshi for parsing Kotlin Objects but I forgot the ScalarsConverter

//Build Retrofit Object
val retrofit =
    Retrofit.Builder()
        .addConverterFactory(ScalarsConverterFactory.create())
        .addConverterFactory(MoshiConverterFactory.create(moshi))
        .baseUrl(BASE_URL)
        .build()
Tonnie
  • 4,865
  • 3
  • 34
  • 50