How to mock return type and verify method is called

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How to mock return type and verify method is called

Joe Schafer
Hi all,

I'm trying to unit-test a resource class in Dropwizard with the Spock.

POSTing a `Todo` to `/` should add the `Todo` to the database and return the added `Todo`.  The code works as intended when I run it, I just can't figure out how to test it.

I want to verify three things:

1. I get a `Todo` back from the POST
2. I get a OK (200) status.
3. `TodoStore.save` is called once.

The test below only works for item 3.  How do I fix item 1 and 2?

The full working code is available at Github at the relevant commit.  The relevant sections are below.


### TodoResourceTest.groovy

    class TodoResourceTest extends Specification {

        TodoStore todoStore = Mock(TodoStore)

        @Rule
        ResourceTestRule resources = ResourceTestRule.builder()
                .addResource(new TodoResource(todoStore))
                .build()

        def "Adding a todo increases number of Todos"() {
            given: "no todos in TodoStore"
                Todo todo = new Todo(1, "title", null, null, null)
                todoStore.save(_ as Todo) >> todo

            when: "we add a Todo"
                def response = resources.client().target("/")
                    .request(APPLICATION_JSON_TYPE)
                    .post(entity(todo, APPLICATION_JSON_TYPE))
            then:
                // HELP: How do you test that the returned Todo is the same?

                // FAILS: Why doesn't this pass, it's returning 204 (no content) instead of 200
                // Why isn't is returning the todo as specified in the "given" block?
                response.getStatusInfo() == Response.Status.OK
                
                // PASSES
                1 * todoStore.save(_ as Todo)
        }
    }
    
### TodoResource.java

    @Path("/")
    @Produces(MediaType.APPLICATION_JSON)
    public final class TodoResource {

        private final TodoStore todoStore;

        @Inject
        public TodoResource(TodoStore todoStore) {
            this.todoStore = todoStore;
        }

        @Timed
        @POST
        public Todo addTodo(Todo todo) {
            return todoStore.save(todo);
        }
    }


### TodoStore.java - this is mocked, so it shouldn't matter

    public class TodoStore {

        private final DSLContext db;

        @Inject
        public TodoStore(DSLContext db) {
            this.db = db;
        }

        public Todo save(Todo todo) {
            final TodoRecord todoRecord = db.newRecord(TODO, todo);

            // id is determined by database, not user
            todoRecord.changed(TODO.ID, false);

            // url is determined based on id
            todoRecord.setUrl(null);

            if (todoRecord.getCompleted() == null) {
                todoRecord.setCompleted(false);
            }

            todoRecord.store();

            return todoRecord.into(Todo.class);
        }
    }

I copied this over from http://stackoverflow.com/questions/35329531/use-spock-testing-library-to-test-post-to-dropwizard-resource, where it didn't seem like it got any attention.  I'll transfer any answers back over.

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to mock return type and verify method is called

Kostis Kapelonis
As you have found already (and posted in Stack overflow), when it
comes to mocks you have to stub them and examine them in the same
statement.

I have to admit that the Mockito way (where stubbing and expected
results are not tied together) sometimes feels more natural (at least
to me)

Kostis

On Fri, Feb 12, 2016 at 12:49 AM, Joe Schafer <[hidden email]> wrote:

> Hi all,
>
> I'm trying to unit-test a resource class in Dropwizard with the Spock.
>
> POSTing a `Todo` to `/` should add the `Todo` to the database and return the
> added `Todo`.  The code works as intended when I run it, I just can't figure
> out how to test it.
>
> I want to verify three things:
>
> 1. I get a `Todo` back from the POST
> 2. I get a OK (200) status.
> 3. `TodoStore.save` is called once.
>
> The test below only works for item 3.  How do I fix item 1 and 2?
>
> The full working code is available at Github at the relevant commit.  The
> relevant sections are below.
>
>
> ### TodoResourceTest.groovy
>
>     class TodoResourceTest extends Specification {
>
>         TodoStore todoStore = Mock(TodoStore)
>
>         @Rule
>         ResourceTestRule resources = ResourceTestRule.builder()
>                 .addResource(new TodoResource(todoStore))
>                 .build()
>
>         def "Adding a todo increases number of Todos"() {
>             given: "no todos in TodoStore"
>                 Todo todo = new Todo(1, "title", null, null, null)
>                 todoStore.save(_ as Todo) >> todo
>
>             when: "we add a Todo"
>                 def response = resources.client().target("/")
>                     .request(APPLICATION_JSON_TYPE)
>                     .post(entity(todo, APPLICATION_JSON_TYPE))
>             then:
>                 // HELP: How do you test that the returned Todo is the same?
>
>                 // FAILS: Why doesn't this pass, it's returning 204 (no
> content) instead of 200
>                 // Why isn't is returning the todo as specified in the
> "given" block?
>                 response.getStatusInfo() == Response.Status.OK
>
>                 // PASSES
>                 1 * todoStore.save(_ as Todo)
>         }
>     }
>
> ### TodoResource.java
>
>     @Path("/")
>     @Produces(MediaType.APPLICATION_JSON)
>     public final class TodoResource {
>
>         private final TodoStore todoStore;
>
>         @Inject
>         public TodoResource(TodoStore todoStore) {
>             this.todoStore = todoStore;
>         }
>
>         @Timed
>         @POST
>         public Todo addTodo(Todo todo) {
>             return todoStore.save(todo);
>         }
>     }
>
>
> ### TodoStore.java - this is mocked, so it shouldn't matter
>
>     public class TodoStore {
>
>         private final DSLContext db;
>
>         @Inject
>         public TodoStore(DSLContext db) {
>             this.db = db;
>         }
>
>         public Todo save(Todo todo) {
>             final TodoRecord todoRecord = db.newRecord(TODO, todo);
>
>             // id is determined by database, not user
>             todoRecord.changed(TODO.ID, false);
>
>             // url is determined based on id
>             todoRecord.setUrl(null);
>
>             if (todoRecord.getCompleted() == null) {
>                 todoRecord.setCompleted(false);
>             }
>
>             todoRecord.store();
>
>             return todoRecord.into(Todo.class);
>         }
>     }
>
> I copied this over from
> http://stackoverflow.com/questions/35329531/use-spock-testing-library-to-test-post-to-dropwizard-resource,
> where it didn't seem like it got any attention.  I'll transfer any answers
> back over.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Spock Framework - User" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [hidden email].
> To post to this group, send email to [hidden email].
> Visit this group at https://groups.google.com/group/spockframework.
> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Loading...