I'm looking for a way to test if some given List is an unmodifiable one.
I have an object that has a List<NoMatter>
, in order to offer methods such as addNoMatter(NoMatter nm)
instead of allowing the API client to simply do .getNoMatters().add(nm);
I always return an unmodifiable version of this list, so the client is still able to have the list. I do it as follows:
public List<NoMatter> getNoMatters() { return Collections.unmodifiableList(this.noMatters); }
The problem is that when I'm doing my tests I simply cant check if this object is of type UnmodifiableList. My first try was doing:
@Test public void checkIfListIsImmutable(){ assertTrue("List is not immutable", this.myObj.getNoMatters() instanceof UnmodifiableList); }
Happens that I cant seem to be able to import the type UnmodifiableList
neither java.util.Collections$UnmodifiableRandomAccessList
that is what I get when I try System.out.println(myObj.getNoMatters().getClass().getName());
at the console.
So how can I achieve it???
PS.: I know I can pass this test by doing:
@Test(expected = UnsupportedOperationException.class) public void checkIfListIsImmutable(){ this.myObj.getNoMatters().add(null); }
EDIT: The above test doesn't grants me that the list Im dealing with isn't immutable as I would need to have tests to every method that may modify my original list, including .remove(), .clear(), .shuffle(), etc! thats why I do not think this is a nice way to proceed.
>>> But I still believe that its not even close to an elegant solution! <<<
I suggest using "addAll(Collections. emptyList());" instead of add(null) to test for immutable. This will raise the UnsupportedOperationException if immutable and does not modify the list if mutable.
list) did. This is due to the fact that Object is a supertype of all Java objects, and basically everything extends Object. So, a List of Integers gets processed as well.
I think your solution is not only reasonable, it is elegant. You want to test that you cannot modify the list, and your test proves it succinctly. Testing the name of the class tests the name, not the behavior. In this case, who cares about the name?
Likewise, if I wanted to test that I cannot pass null to some method, I'd pass null in a test and expect an IllegalArgumentException.
I actually think that is your best bet. Your alternative (less elegant) way is to check the name of the class.
this.myObj.getNoMatters().getClass().getSimpleName().equals("UnmodifiableCollection")
The issue for you is the wrapped UnmodifiableCollection is package-private.
I don't see anything wrong with expecting an exception there, but that's just me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With