Test error case in wormwood

Hi everyone,

Can’t find any error map in wormwood

My test works but I can’t test an error

describe "GetMenuItems.gql == error" do
    test "Should return error Menu items (0 of them)" do
      result = query_gql(variables: %{"matching" => "123"})
      IO.inspect(result)
      assert {:ok, %{data: %{"MenuItems" => menu_items}}} = result

      IO.inspect(menu_items)

      assert length(menu_items) == 0
    end
  end

This all I have

{:ok, %{data: %{"MenuItems" => []}}}

Am I missing something?

Thanks

Why should that return an error? 0 results isn’t an error. Additionally, a graphql query will only return an error if there is a syntax / validation issue with the query itself, or if you return an error from the resolver. If you aren’t doing that, it won’t error.

1 Like

Thank you

I was trying to rewrite this test in Wormwood:

@query """
  {
    menuItems(matching: 123) {
      name
    }
  }
  """
  test "menuItems field returns errors when using a bad value" do
    response = get(build_conn(), "/api", query: @query)
    assert %{"errors" => [
      %{"message" => message}
    ]} = json_response(response, 400)
    assert message == "Argument \"matching\" has invalid value 123."
  end

And i don’t see any possibilities at the moment to do so.

You didn’t pass in the same value. You passed in "123" (a string), but the wormwood example uses 123 (an integer).

1 Like

You are right. Now I will match it with the error I am getting. Thanks

FYI this line doesn’t do anything. You’re just binding a value to a variable, which cannot fail.

1 Like

So now after rewriting this test

describe "GetMenuItems.gql == error" do
    test "Should return error Menu items (error)" do
      result = query_gql(variables: %{"matching" => 123})
      IO.inspect(result)

      assert {:ok, %{"errors" => [%{"message" => message}]}} = result

      assert message = [%{"message" => "Argument \"matching\" has invalid value $matching."}]
    end
  end

I don’t get a pass

I was trying to pattern match on the error message like in the previous tests but no luck.

Stack trace:

mix test test/plate_slate_web/schema/query/menu_items_test.exs

...{:ok,
 %{
   errors: [
     %{
       locations: [%{column: 0, line: 4}],
       message: "Argument \"matching\" has invalid value $matching."
     }
   ]
 }}


  1) test GetMenuItems.gql == error Should return error Menu items (error) (PlateSlateWeb.Schema.Query.MenuItemsTest)
     test/plate_slate_web/schema/query/menu_items_test.exs:31
     match (=) failed
     code:  assert {:ok, %{"errors" => [%{"message" => message}]}} = result
     right: {:ok,
             %{
               errors: [
                 %{
                   locations: [%{column: 0, line: 4}],
                   message: "Argument \"matching\" has invalid value $matching."
                 }
               ]
             }}
     stacktrace:
       test/plate_slate_web/schema/query/menu_items_test.exs:35: (test)



Finished in 1.1 seconds
4 tests, 1 failure

Randomized with seed 419754

I’m happy to keep helping you, but there are some Elixir basics here you seem to be struggling with that are making this a lot harder than it needs to be. Look carefully at the error message. Look at the exact data types between what you have what you are asserting on the left, and what the value of result is on the right. In particular, pay attention to what values are strings and what values are atoms.

Based on the content of your error messages, it looks like you’re working through the Absinthe book. This is a great way to learn absinthe. However, since you’re very new to this, I don’t think it’s a good idea to try to BOTH work through a new book AND utilize a testing library that isn’t used in the book. There are subtle but important differences between how wormwood tests work and how regular ExUnit test work, and those differences will only increase as you go further into the book and start handling things like authentication headers. I would ditch wormwood for now, and revisit it later after you have a solid grasp of how Absinthe and Elixir testing works.

2 Likes

I appreciate the recommendation but when i used the tests in the book I run only into errors and erratas like this one

  • Reported in: P1.0 (31-Mar-19)
  • Fixed: 28-May-19, awaiting book release

#84808
PDF page: 36

@query “”"
{
menuItems(matching: 123) {
name
}
}
“”"
test “menuItems field returns errors when using a bad value” do
response = get(build_conn(), “/api”, query: @query)

assert %{
“errors” => [
%{“message” => message}
]
} = json_response(response, 400)

assert message == “Argument “matching” has invalid value 123.”
end

$ mix test test/plate_slate_web/schema/query/menu_items_test.exs

  1. test menuItems field returns errors when using a bad value (PlateSlateWeb.Schema.Query.MenuItemsTest)
    test/plate_slate_web/schema/query/menu_items_test.exs:76
    ** (RuntimeError) expected response with status 400, got: 200, with body:
    {“errors”:[{“message”:“Argument “matching” has invalid value 123.”,“locations”:[{“line”:2,“column”:0}]}]}
    code: } = json_response(response, 400)
    stacktrace:
    (phoenix) lib/phoenix/test/conn_test.ex:373: Phoenix.ConnTest.response/2
    (phoenix) lib/phoenix/test/conn_test.ex:419: Phoenix.ConnTest.json_response/2
    test/plate_slate_web/schema/query/menu_items_test.exs:83: (test)

Finished in 0.2 seconds
3 tests, 1 failure–Conrad Taylor

Ben Wilson says: This happened because you upgraded absinthe_plug which has slightly different behaviour with respect to status codes. Using the version specified in the book lock file will ensure that the book code works.

I don’t ewnat to complain i just searched for a solution for myself.

Thank you a lot for all the suport and patience in guiding me with this.

The answer I supply in the errata is the correct one to solve your problem. Did you try using the exact mix.lock file from the book code?

I wanted to use the latest, because that is what i will use in production and wormwood helped me to use the latest until now.

This is a good idea for production, but not a good idea when at the “learn from a book” stage. You always should use the exact versions specified in the book unless you are sufficiently familiar with the subject matter to make the necessary changes.

In this specific case, the change is extremely minor, so it’s up to you. If you want to use latest you can, but you’ll want to do json_response(response, 200) instead of json_response(response, 400). My recommendation is to stick to the book versions while learning from the book. There are very few things different between the book version and the latest Absinthe version, but there are enough that it can confuse beginners. Go through the book till you have some comfort with it, then do your new project on the latest version.

1 Like

Thanks,

Also because i have my test to this stage in absinthe can you tell me why doesn’t the message pattern match?

{:ok,
             %{
               errors: [
                 %{
                   locations: [%{column: 0, line: 4}],
                   message: "Argument \"matching\" has invalid value $matching."
                 }
               ]
             }}

has atom keys

assert {:ok, %{"errors" => [%{"message" => message}]}} = result

has string keys.
specifically the keys :errors and :message.

1 Like

This works

describe "GetMenuItems.gql == error" do
    test "Should return error Menu items (error)" do
      result = query_gql(variables: %{"matching" => 123})
      IO.inspect(result)

      assert {:ok, %{errors: [%{message: message}]}} = result

      IO.inspect(message)

      assert message = %{message: "Argument \"matching\" has invalid value $matching."}
    end
  end

Also when in doubt just IO.inspect the result of query this one, like this:

result = query_gql(variables: %{"matching" => 123})
IO.inspect(result)

I hope this will help others.

What i learned that you need to read twice and write once.

Thanks for the help @benwilson512

1 Like

As I noted before though, this isn’t doing what you think it’s doing. This is NOT testing anything, it cannot fail, it is literally not a test for anything. You’re assigning a variable, which always succeeds. You can prove this to yourself by changing that line to assert message = :foo. That will also pass. You need to use ==, and you’ll probably need to change $matching to an actual value.

You are right, but when you don’t have documentation you can only guess. That is my case with Wormwood where i have a gql files for all the tests something like this:

query($matching: String) {
  MenuItems(matching: $matching) {
    ...MenuItemFields
  }
}
fragment MenuItemFields on MenuItem {
  id
  name
}

My final version.

Explanation: I think this could be a good test because if the message variable has that value then the assert will be true if not it will be false.

describe "GetMenuItems.gql == error" do
    test "Should return error Menu items (error)" do
      term = 123
      result = query_gql(variables: %{"matching" => term})
      IO.inspect(result)

      assert {:ok, %{errors: [%{message: message}]}} = result

      assert message == "Argument \"matching\" has invalid value $matching."
    end
  end

To be clear, the assert message = issue I’m speaking about is part of how Elixir works, it has nothing to do with wormwood.

I’m glad you’ve gotten un stuck. I’m probably not going to pitch in on further wormwood questions though, I already went to the effort of writing out the book with all of its tests, I unfortunately do not have time to do a walk through with an entirely different testing framework. Maybe there are others who use it who can help.

1 Like

Thank you for the help and patience.