question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Immutability test failing

See original GitHub issue
import java.util.ArrayList;
import java.util.List;

public final class Student {
    private final int id;
    private final String name;
    private final List<String> hobbies;

    Student(int id, String name, List<String> hobbies) {
        this.id = id;
        this.name = name;
        this.hobbies = hobbies;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public List<String> getHobbies() {
        return new ArrayList<> (hobbies);
    }

}

When I tried to test for immutability using “assertImmutable(Student.class);”, I am getting following error.

Attempt to wrap mutable collection using a non-whitelisted unmodifiable wrapper method. [Field: hobbies…]

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
Grundlefleckcommented, May 15, 2016

Hi,

While Stephan is correct that wrapping in unmodifiable in the getter makes the class immutable, unfortunately Mutability Detector does not realise that. It’s analysis is a bit too naïve.

I suggest copying and wrapping in the constructor:

this.hobbies = Collections.unmodifiableList(new ArrayList<>(hobbies));

That should make the test pass and have other benefits:

  • only one instance of the unmodifiable wrapper needs to be constructed even if the getter is called many times
  • it’s harder to accidentally mutate the collection within this class

Let us know how that works for you.

Cheers!

P.S. really satisfying to see other people helping out on issues, thanks Stephan. On 15 May 2016 8:13 pm, “harikrishna553” notifications@github.com wrote:

Stephen, I got it what you are saying. I am still getting same error when testing ‘assertImmutable(Student.class)’ the Student class.

org.mutabilitydetector.unittesting.MutabilityAssertionError: Expected: mutability.Student to be IMMUTABLE but: mutability.Student is actually NOT_IMMUTABLE Reasons: Field can have a mutable type (java.util.ArrayList) assigned to it. [Field: hobbies, Class: mutability.Student] Allowed reasons: None. at org.mutabilitydetector.unittesting.internal.AssertionReporter.assertThat(AssertionReporter.java:48) at org.mutabilitydetector.unittesting.MutabilityAsserter.assertImmutable(MutabilityAsserter.java:108) at org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutable(MutabilityAssert.java:672) at mutability.TestMutability.checkMyClassIsImmutable(TestMutability.java:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Following i my Test class.

import static org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutable;

import org.junit.Test;

public class TestMutability {

@Test
public void checkMyClassIsImmutable() {
    assertImmutable(Student.class);
}

}

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/MutabilityDetector/MutabilityDetector/issues/86#issuecomment-219304639

0reactions
Stephan202commented, May 16, 2016

@Grundlefleck, good suggestion on moving everything in the constructor; I almost feel dumb for not suggesting it myself. I guess it’s because in my own code I always use Guava’s immutable collections, so I haven’t recently used the “JDK-only” approach. Anyway, happy to help!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Testing Object's Immutability: Is This a Good Idea?
The crazy thing here is that you might not realize an immutability failure, they are usually hard to catch, because, they appear in...
Read more >
Unit test is failing while converting an entity to Immutable ...
I was able to convert an entity to Immutable model object but unit test is failing for this. It is throwing NPE at...
Read more >
Your Unit Tests Should Be Immutable - DEV Community ‍ ‍
If you go into those failing tests and update the tests with the new assumption it's highly likely that an error will get...
Read more >
Class invariants, immutability, and testing
Class invariants, immutability, and testing. Josh Bloch ... Implementation testing with assertions ... Never write code without a failing test.
Read more >
Unit testing Java data classes immutability with the Mutability ...
the test will fail if the class is not immutable. For example, if a field is not final and it has a setter...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found