How to mock return type and verify method is called

413 views
Skip to first unread message

Joe Schafer

unread,
Feb 11, 2016, 6:22:37 PM2/11/16
to Spock Framework - User
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.

Kostis Kapelonis

unread,
Mar 8, 2016, 5:08:52 PM3/8/16
to spockfr...@googlegroups.com
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
> --
> 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 spockframewor...@googlegroups.com.
> To post to this group, send email to spockfr...@googlegroups.com.
> Visit this group at https://groups.google.com/group/spockframework.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages