最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to generate test data instances of immutable java class without code duplication? - Stack Overflow

programmeradmin2浏览0评论

I have a large class, marked with @Value from lombok, making it immutable. It is validated at some point, and in order to unit test these validations, I have to produce numerous versions of this object, with small deviations from a valid instance. I am looking for a way to make these changes without writing the whole generation every time. If the class was mutable, I could just apply my changes to a freshly generated valid instance for each test.

One solution would be creating a new class with the same format, but mutable, and passing that to the immutable object generator, after the necessary changes where applied, but this is not ideal.

Is there a way to parametrize this in a more sensible manner?

@Value
class MyClass{
    String a;
    String b;
    String c;
    ...
}

// if it was mutable, I could just do this:

getValid() {
    return new MyClass("a","b","c"...);
}

testA() {
    var obj = getValid();
    obj.a = "invalid";
    // ... do test here
}

testB() {
    var obj = getValid();
    obj.b = "invalid";
    // ... do test here
}

testC() {
    var obj = getValid();
    obj.c = "invalid";
    // ... do test here
}

...

// since it is immutable, I have to do this:

testA() {
    var obj = new MyClass("invalid","b","c"...); // I would like to avoid this
    // ... do test here
}

testB() {
    var obj = new MyClass("a","invalid","c"...); // I would like to avoid this
    // ... do test here
}

testC() {
    var obj = new MyClass("a","b","invalid"...); // I would like to avoid this
    // ... do test here
}

...

I have a large class, marked with @Value from lombok, making it immutable. It is validated at some point, and in order to unit test these validations, I have to produce numerous versions of this object, with small deviations from a valid instance. I am looking for a way to make these changes without writing the whole generation every time. If the class was mutable, I could just apply my changes to a freshly generated valid instance for each test.

One solution would be creating a new class with the same format, but mutable, and passing that to the immutable object generator, after the necessary changes where applied, but this is not ideal.

Is there a way to parametrize this in a more sensible manner?

@Value
class MyClass{
    String a;
    String b;
    String c;
    ...
}

// if it was mutable, I could just do this:

getValid() {
    return new MyClass("a","b","c"...);
}

testA() {
    var obj = getValid();
    obj.a = "invalid";
    // ... do test here
}

testB() {
    var obj = getValid();
    obj.b = "invalid";
    // ... do test here
}

testC() {
    var obj = getValid();
    obj.c = "invalid";
    // ... do test here
}

...

// since it is immutable, I have to do this:

testA() {
    var obj = new MyClass("invalid","b","c"...); // I would like to avoid this
    // ... do test here
}

testB() {
    var obj = new MyClass("a","invalid","c"...); // I would like to avoid this
    // ... do test here
}

testC() {
    var obj = new MyClass("a","b","invalid"...); // I would like to avoid this
    // ... do test here
}

...
Share Improve this question asked Mar 13 at 11:39 maybesomenamemaybesomename 1751 silver badge12 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

Use @With annotation. It generates withXxx() methods. Those methods allow to create copy of object with single property changed.

Alternatively you can use @Builder annotation and make your factory method return builder. You can configure it before calling build().

MyClass.MyClassBuilder b = myFactoryMethod();
MyClass v = b.a("").build();
发布评论

评论列表(0)

  1. 暂无评论