Question

I am looking for a Java tool that would create anonymous variables (variables whose value I don't care about) in my tests, similar to AutoFixture in .Net. Here is a link to AutoFixture's readme, which has pretty good examples of what it does.

Here is a short example taken from the same readme:

[TestMethod]
public void IntroductoryTest()
{
    // Fixture setup
    Fixture fixture = new Fixture();

    int expectedNumber = fixture.CreateAnonymous<int>();
    MyClass sut = fixture.CreateAnonymous<MyClass>();
    // Exercise system
    int result = sut.Echo(expectedNumber);
    // Verify outcome
    Assert.AreEqual<int>(expectedNumber, result, "Echo");
    // Teardown
}

Is there such a tool in the Java world?

Edit:

I tried QuickCheck and while it managed to do something like what I was looking for:

import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;
import net.java.quickcheck.generator.support.ObjectGeneratorImpl;

public class Main {

interface Test{
     String getTestValue();
}

public static void main(String[] args) {
    Generator<String> stringGen = PrimitiveGenerators.strings(5, 100);
    Generator<Integer> intGen = PrimitiveGenerators.integers(5, 20);

    ObjectGeneratorImpl<Test> g = new ObjectGeneratorImpl<>(Test.class);
    g.on(g.getRecorder().getTestValue()).returns(stringGen);


    for (int i = 0; i < intGen.next(); i++) {
        System.out.println("value of testValue is: " + g.next().getTestValue());
    }
}

}

The tool seems to work only with interfaces. If I change Test to be a class and the method to a field, the generator throws an exception that only interfaces are supported.

I sincerely hope that there is something better, especially since the documentation is seriously lacking.

Was it helpful?

Solution

There is a Java implementation of QuickCheck, which has APIs for generating test data:

http://java.net/projects/quickcheck/pages/Home

I'm not too familiar with AutoFixture, and I suspect that QuickCheck is a slightly different kind of test framework, but maybe it is useful for solving your specific problem.

OTHER TIPS

There's also JFixture which is available on github and published to maven central.

This is still under active development, and feature requests are being honoured.

Ivan,

I started a project focused on reimplementing core features of AutoFixture in java. AutoFixture has certainly a lot of features, so I need to prioritize which ones to implement first and which ones not to bother implementing at all. As the project is just started, I welcome testing, defect reports and feature requests.

I am using JFixture along Mockito.spy() for that ;)

Let's see an example how to do something that it would be trivial with AutoFixture and C#. The idea here is to generate random data in your object except for some specific methods that need to have specific values. It is interesting I didn't find that somewhere stated.. This technique eliminates the "Arrange" part of your unit tests to be a small number of lines and in addition focuses on what values need to be specific for this unit test to pass

public class SomeClass {
    public int id; //field I care
    public String name; // fields I don't care
    public String description; //fields I don't care

    public int getId(){
        return id;
    } 

    public void setId(int id){
        this.id = id;
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public String getDescription(){
        return description;
    }

    public void setDescirption(String description){
        this.description = description;
    }
}



public static void main(String args[]){
    JFixture fixture = new JFixture();
    fixture.customise().circularDependencyBehaviour().omitSpecimen(); //omit circular dependencies
    fixture.customise().noResolutionBehaviour().omitSpecimen(); // omit methods that cannot be resolved
    SomeClass entity = fixture.create(SomeClass.class);
    SomeClass mock = Mockito.spy(entity);
    Mockito.when(mock.getId()).thenReturn(3213);

    System.out.println(mock.getId()); // always 3213
    System.out.println(mock.getName()); // random
    System.out.println(mock.getDescription()); //random
}

This prints:

3213
name9a800265-d8ef-4be9-bd45-f0b62f791d9c
descriptiona9f9245f-eba1-4805-89e3-308ef69e7091

Try object factory. It is open sourced on github. It can create random Java objects in just a single line of code. And it is highly configurable.

Example:

ObjectFactory rof = new ReflectionObjectFactory();

String str = rof.create(String.class);
Customer cus = rof.create(Customer.class);

It is also available in Maven Central Repository.

ObjectGenerator is more of an experimental feature:

ObjectGenerator<Test> objects = PrimitiveGenerators.objects(Test.class);
objects.on(objects.getRecorder().getTestValue()).returns(PrimitiveGenerators.strings());

Test next = objects.next();
System.out.println(next.getTestValue());

I'd prefer a simple Generator implementation:

class TestGenerator implements Generator<Test>{
    Generator<String> values = PrimitiveGenerators.strings();
    @Override public Test next() {
        return new TestImpl(values.next());
    }   
}

Yet Another QuickCheck for Java is another tool you may probably take a look.

It is very integrated with JUnit (it supports tests with parameters, annotations to configure the generated objects and so on).

It has a lot of generators (all of quickcheck, and some specific to OOP, such as interfaces, abstract classes and singleton generators), and you can define your own ones. There is also a constructor-based generator.

Currently is in alpha status, but if you take a look to the downloads page you'll see a basic documentation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top