I have a love/hate relationship with mocks in unit tests. They are wonderful to mock out services, but building mocks or objects with just enough data for testing is often a pain. I end up writing code like:
Person person = new Person(); person.setName("John Doe"); person.setLocation("Brussels"); Organization organization = new Organization(); organizaion.setName("Company Ltd"); person.setOrganization(organization);
I believe this is too verbose to be nice. As such test objects are often needed this code may be moved to a separate class to build test mother objects. This arguably makes things worse by hiding the values used and more or less forcing all tests to use the same field values.
When I need this object to be a Mockito mock it becomes something like this:
Person person = Mockito.mock(Person.class); when(person.getName()).thenReturn("John Doe"); when(person.getLocation()).thenReturn("Brussels"); Organization organization = mock(Organization.class); when(organizaion.getName()).thenReturn("Company Ltd"); when(person.getOrganization()).thenReturn(organization);
This is not very readable.
Taking inspiration from faker gems in Ruby, I created a new library to make this more legible.
Person person = FakerMock.withFields(Person.class, "name", "John Doe", "location", "Brussels", "organization", FakerMock.withFields(Organization.class, "name", "Company Ltd"));
This is now available as jFaker.
This is a reasonable simple start, but I would like to extend this to also support javabeans (same syntax but using FakerBean instead of FakerMock) and also te be able to have values read from a yaml file. In that case, I would probably use a syntax like
FakerBuilder faker = new FakerBuilder(). withYaml("my/yaml/file/with/general/defaults.yml"); withYaml("my/yaml/file/with/defaults/for/this/test.yml"); Person person = faker.withFields(Person.class, "name", "John Doe", "location", "Brussels", "organization", faker.withFields(Organization.class, "name", "Company Ltd"));
Would this be useful for you?