ssacher-tgm / mockito

Automatically exported from code.google.com/p/mockito
0 stars 0 forks source link

Provide a simple way to define return values each method of a class that you're mocking #187

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Enhancement request:

I've used the ObjectMother and TestBuilder pattern numerous times on
different projects in order to create real domain classes for testing. The
overhead of creating and maintaining these is high, but the reusability is
great, particularly when you have a large graph of domain objects. Also,
the tests are much cleaner than when mocking the domain objects (IMHO).

What I would like to see is a simple way of defining a mapping between
method calls and return values. You could then inject this mapping when you
define your mock so that as each method is called, the return values are
retrieved from this mapping. Ideally this would be done in a typesafe way
so that when you refactor the methods in the mapping, the compiler would
pick up these changes.

Currently Mockito only allows you to define a default Answer for unstubbed
methods. The result of this enhancement would be that you could effectively
do the same thing as you would when creating an object with the test
builder pattern, but in a much simpler way using Mockito. Multiple tests
could reuse the map/maps that were created. 

What I'm envisioning is something like this:

class PersonAnswerMap {
    void createMap() {
        map(person.getFirstName()).to("John");
        map(person.getLastName()).to("Doe");
        map(person.getAddress()).to(mock(new Address(),
AddressAnwerMap.class));
    }
}

class AddressAnswerMap {
    void createMap() {
        map(address.getState()).to("TX");
        map(address.getCity()).to("Houston");
    }
}

Test:
----
//Create the object graph with all my default values from the mappings
Person person = mock(person, PersonAnswerMap.class)

//Override just the values that I actually care about for my test
when(person.getLastName()).thenReturn("Johnson");

assertEquals("John", person.getFirstName());
assertEquals("Johnson", person.getLastName());
assertEquals("TX", person.getAddress().getState());
assertEquals("Houston", person.getAddress().getCity());

Original issue reported on code.google.com by javidja...@gmail.com on 5 May 2010 at 7:51

GoogleCodeExporter commented 8 years ago
Hey,

I think what you are proposing is some extra support for mocking complex value
objects (or entities). Not sure if it is a good idea. Wouldn't you prefer to 
have
fluent builders for building up the state?

//Instead: 
Person person = mock(person, PersonAnswerMap.class)
//You do:
Person person = new PersonBuilder().build();
//or
Person person = new PersonBuilder().withDefaults().build();
//In case you want to override some defaults:
Person person = new PersonBuilder().name("foo").id(102).build();

Also, have a look at:
http://code.google.com/p/fluent-builders-generator-eclipse-plugin/

Original comment by szcze...@gmail.com on 24 May 2010 at 6:06

GoogleCodeExporter commented 8 years ago
Hey,

I think what you are proposing is some extra support for mocking complex value
objects (or entities). Not sure if it is a good idea. Wouldn't you prefer to 
have
fluent builders for building up the state?

//Instead: 
Person person = mock(person, PersonAnswerMap.class)
//You do:
Person person = new PersonBuilder().build();
//or
Person person = new PersonBuilder().withDefaults().build();
//In case you want to override some defaults:
Person person = new PersonBuilder().name("foo").id(102).build();

Also, have a look at:
http://code.google.com/p/fluent-builders-generator-eclipse-plugin/

Original comment by szcze...@gmail.com on 24 May 2010 at 6:06

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago

Original comment by szcze...@gmail.com on 30 May 2010 at 6:24