有没有Java替代Ploeh的AutoFixture用于.Net?

27
我正在寻找一个Java工具,可以在我的测试中创建匿名变量(我不关心其值的变量),类似于.Net中的AutoFixture。这里有一个链接到AutoFixture的自述文件,其中有很好的示例。
以下是从同一自述文件中摘取的简短示例:
[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
}

在Java世界中有这样的工具吗?
编辑:
我尝试了QuickCheck,虽然它成功地做到了我想要的一些东西:
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());
    }
}

}

这个工具似乎只能处理接口。如果我将Test更改为类,并将方法更改为字段,生成器会抛出一个异常,说明仅支持接口。
我真诚地希望有更好的解决方案,尤其是因为文档严重缺失。

1
每当在 Stack Overflow 上找到与我问题完全相同的答案时,我总是会露出灿烂的微笑。(我知道这个评论并没有太多价值...) - Bruno Brant
7个回答

9

还有JFixture,它可以在github上获取,并发布到maven中央仓库

这个工具仍在积极开发中,特性请求正在得到支持。


这看起来非常有前途! - Jan

4

你做得怎么样了? - John Zabroski
它可以工作,你可以在Maven中央找到二进制文件。我只实现了我使用的AutoFixture部分,所以可能会有一些缺失(我欢迎问题)。它需要Java 8。还有一种替代方案,即JFixture(请参见Jane Nicholson的答案),似乎正在积极开发中,所以我认为你可以自由选择 :-)。 - Grzesiek Galezowski

3
尝试使用对象工厂。它在github上开源。它可以在仅一行代码中创建随机的Java对象。而且它高度可配置。
例如:
ObjectFactory rof = new ReflectionObjectFactory();

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

它也可以在Maven中央仓库中获得。


3

我正在使用JFixtureMockito.spy()。;)

让我们看一个例子,如何使用AutoFixture和C#做一些微不足道的事情。这里的想法是在对象中生成随机数据,除了一些需要具有特定值的特定方法。有趣的是,我没有找到任何地方提到过这种技术.. 这种技术可以消除单元测试中“安排”部分的大量代码,并且还可以专注于哪些值需要特定才能通过此单元测试。

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
}

这将打印:

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

3

有一个Java实现的QuickCheck,它具有生成测试数据的API:

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

我不太熟悉AutoFixture,我怀疑QuickCheck是一种稍微不同类型的测试框架,但也许它对解决您的特定问题有用。


谢谢。虽然缺乏文档令人惊讶,但这似乎可以完成工作。此外,文档声称支持 POJO 生成,但当我尝试这样做时,生成器会抛出异常“仅支持接口”。 - Ivan Alagenchev
@IvanAlagenchev 是的,文档不是很好。看起来你需要构建一个自定义生成器来完成你想要的类和字段POJO生成。这里有一个例子:http://java.net/projects/quickcheck/sources/repository/content/quickcheck-examples/src/test/java/FileGeneratorTest.java - Chris Vest

2

ObjectGenerator更多是一个实验性功能:

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

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

我更喜欢一个简单的生成器实现:

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

谢谢@Thomas Jung,我会采用这种方法来处理复杂的类。 - Ivan Alagenchev

0

Java的另一个QuickCheck是另一个你可能会感兴趣的工具。

它与JUnit非常集成(支持带参数的测试,注释来配置生成的对象等)。

它有很多生成器(所有的quickcheck,以及一些特定于OOP的,如接口、抽象类和单例生成器),你也可以定义自己的生成器。还有一个基于构造函数的生成器。

目前处于alpha状态,但如果你查看下载页面,你会看到基本文档。


谢谢提供链接。我看了一下,有两个原因让我不打算在我的项目中使用它。第一个是它由大学支持 - 我对使用这样的项目感到非常紧张。通常没有人在研究生离开后维护。第二个原因是它自去年四月以来没有更新过。不过我会关注一下,如果有活动的话,我可能会选择它而不是QuickCheck的Java实现。 - Ivan Alagenchev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接