简体   繁体   中英

Are there any tools to create dummy objects to use for JUnit test cases?

I am writing JUnit test cases to test CRUD operations in DAO classes. It is pretty much boilerplate code and bulk of it is to create the test object and assign dummy values to the instance variables. Are there any tools in Java to create an object and assign dummy values based on the declared type?

I don't want to use JMock or Mockito as I need to interact with the database and test that the CRUD operations are successful.

A bit late to the party, but lorem-ipsum-objects can generate test data of any type for you on the fly.

Here's the basic usage example from the main page:

Basic usage:

 LoremIpsumObjectCreator creator = new LoremIpsumObjectCreator(); creator.createLoremIpsumObject(clazz);

Usage with custom factories:

 ClassBindings classBindings = new ClassBindings(); // or: ClassBindings classBindings = ClassBindings.defaultBindings(); // defaults for collections classBindings.add(List.class, new ClassBasedFactory<>(ArrayList.class)); LoremIpsumObjectCreator creator = new LoremIpsumObjectCreator(classBindings); creator.createLoremIpsumObject(clazz);

To apply this to the example mentioned in the currently accepted answer:

Foo foo = new Foo();
foo.setIntValue(creator.createLoremIpsumObject(int.class));
foo.setStringValue(creator.createLoremIpsumObject(String.class));

Or even better:

Foo foo = creator.createLoremIpsumObject(Foo.class);

I don't know a tool which will create a mock object for you and fill it automatically with some fuzzy data.

But maybe the following approach would be close to what you want to achieve.

pseudo code

Foo foo = new Foo();
foo.setIntValue(generateInt());
foo.setStringValue(generateString(20));
...
// store the record in the database
// retrieve the record from the database
// check if the retrieved values are equal to the values in `foo`

If this is what you want to achieve you might have a look for QuickCheck

The goal of QuickCheck is to replace manually picked values with generated values. A QuickCheck-based test tries to cover the laws of a domain whereas classical testing can only test the validity for distinct values.

Basically, QuickCheck is about generators of data. The QuickCheck runner method is just a fancy for loop implementation. QuickCheck can help in scenarios where whole classes of test cases have to be tested and it is not feasible to write tests for all distinct test scenarios.

So you could create your own Generator which provides instances of Foo already filled with fuzzy data. In combination with Junit Theories you would be close to your initial requirement.

An example for using Theories with a custom generator you can find here . The example was written for a similar library ( junit-quickcheck ). But it should demonstrate your the idea.

edit Roughly based on the junit-quickcheck example. It might look as in the following snippet.

import net.java.quickcheck.Generator;
import static net.java.quickcheck.generator.PrimitiveGenerators.characters;

public class MyCharacterGenerator implements Generator<String> {

    private static final String LOWERCASE_CHARS = "abcdefghijklmnopqrstuvwxyz";
    private static final String UPPERCASE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String NUMBERS = "0123456789";
    private static final String SPECIAL_CHARS = ".-\\;:_@[]^/|}{";
    private static final String ALL_MY_CHARS = LOWERCASE_CHARS
            + UPPERCASE_CHARS + NUMBERS + SPECIAL_CHARS;
    public static final int CAPACITY = 40;

    Generator<Character> characterGenerator = characters(ALL_MY_CHARS);

    public String generate() {
        StringBuilder sb = new StringBuilder(CAPACITY);
        for (int i = 0; i < CAPACITY; i++) {
            sb.append(characterGenerator.next());
        }
        return sb.toString();
    }

    @Override
    public String next() {
        return generate();
    }
}

.

import net.java.quickcheck.Generator;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;

public class MyCharacterGeneratorTest {

    @Test
    public void testStringGenerator() {
        Generator<String> fuzzyString = new MyCharacterGenerator();

        for (int i = 0; i < 10; i++) {
            String fuzzy = fuzzyString.next();
            System.out.println("fuzzy: " + fuzzy);
            assertTrue(fuzzy.length() == MyCharacterGenerator.CAPACITY);
            assertTrue(fuzzy.matches("[a-zA-Z0-9.\\-\\\\;:_@\\[\\]^/|}{]*"));
        }
    }
}

output

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running MyCharacterGeneratorTest
fuzzy: ;d|xrS|dFS3H@xZRnzE6N\.ly600{C@ll;de5:jN
fuzzy: UCZBO|QJ/6fLqBH9QwFpPcUK.Qa5hEgFR_3A1@;b
fuzzy: Jg}xD44_AFVqy\UKMehGPnV8xmKKy]dDXJsYIG9C
fuzzy: k-eN-Sf^eK.bqqn4PR2[93{wyzgwr_F_ktBGkTP}
fuzzy: 1UDChf3aWN0d/95@}K[W2|P]}.ePzKvRJMJtB0/Z
fuzzy: @J2}kMK@.uZY]smpKWZ;C4@p-Kp9}KUtan@oVLX9
fuzzy: goL8o5qz-Ynga:i;WqGhKTo^1itHqENXM3OrO||4
fuzzy: _\1ifR:ssplcdT9l\s{clV9ZozgCA^I67IF/|t0t
fuzzy: /FwL9nCuRcemqR2SP3|XG9ui5Y21K:r0Ys1XIz/3
fuzzy: 8U[Xk^e60JhGfLTMyGZ:Z;gn9UCXcUEu@wV\oJ7]

Maybe this lib could help you.

six2six/fixture-factory

I've already used it in some projects, including recent ones. It's very simple to use.

One thing I think is worth pointing out is that it seems to me that the lib has not been updated in a few years.

I think what you are looking for is something like Mockito. Mockito gives you the ability to "FAKE" or mock objects and what is returned when a method from that mocked object is called. Mockito can be used to do exactly what you are speaking of and mock an object and what is returned from which ever method all you wish giving you the agility to truly do a unit test with all dependencies under your control.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM