In the current MockHttpSession the methods
setAttribute and removeAttribute are not cooperating.
My suggested patch summerized:
public void removeAttribute(String anAttributeName) {
+ myAttributeValues.remove(anAttributebuteName);
myRemovedAttributes.addActual(anAttributeName);
}
public void setAttribute(String aKey, Object aValue) {
+ if(null==aValue) {
+ removeAttribute(aKey);
+ } else {
myAttributeValues.put(aKey, aValue);
myAttributes.addActual(new MapEntry(aKey,
aValue));
+ }
}
The change in setAttribute is motivated by the quote
"If the value passed in is null, this has the same effect
as calling removeAttribute()."
from the javadoc for this method.
The same mechanism should be implemented for
MockServletContext and MockHttpServletRequest as
well (perhaps as a common super-class).
In the patch I have also used the
identifier "anAttributeName" instead of the previously
used "aKey"
Suggested new version for source file MockHttpSession.java
Logged In: YES
user_id=123464
Can I clarify? Do you have an example of some code that
removes an attribute and gets it within the same test? I
suspect that our thought we hadn't had to do this and so
didn't want to implement the functionality.
Steve
Logged In: YES
user_id=630175
I see your point and the answer to your question is simple:
- No, I do not have any example of some code that removes
an attribute and gets it within the same test.
However, I do have other motives for this patch.
Imagine us having a JUnit test, for the
class 'CloseCaseServlet', containing these test methods:
public void runCloseCaseTest(MockHttpSession aSession) {
/* Prepare the request */
MockHttpServletRequest aRequest= new
MockHttpServletRequest();
aRequest.setSession(aSession);
/* Request the servlet */
new CloseCaseServlet()
.doGet(aRequest, new MockHttpServletResponse());
/* Verify the outcome */
assertNull(aSession.getAttribute("attr1"));
assertNull(aSession.getAttribute("attr2"));
assertNull(aSession.getAttribute("attr3"));
}
public void testCloseBigCase() {
MockHttpSession aSession= new MockHttpSession();
aSession.setAttribute("attr1", new CaseResource1());
aSession.setAttribute("attr2", new CaseResource2());
aSession.setAttribute("attr3", new CaseResource3());
runCloseCaseTest(aSession);
}
public void testCloseSmallCase() {
MockHttpSession aSession= new MockHttpSession();
aSession.setAttribute("attr1", new CaseResource1());
runCloseCaseTest(aSession);
}
The purpose of the tests is to make sure that
CloseCaseServlet clears the session from all case related
information.
The tests are constructed with a state-modeling approach:
- The important thing is that we end up with a correct
session state, where all case resources have been removed.
- It does not matter how the correct session state is reached.
In a first release of the servlet, it is likely that the
removeAttribute(String) method is used for all case attributes,
regardless of whether an attribute is in use or not.
Later on, it is likely that performance problems force a later
release to use some kind of resource pooling. When that is
implemented the method removeAttribute(String) will only be
used for attributes that are actually used.
This kind of test tests the robustness of the servlet and it will
pass regardless of any performance improving changes, as
long as the result stays robust. I find it very convenient to
design some basic robustness tests in this manner. They are
a valuable resource when dealing with performance
improvements at a later stage.
The alternative, using the methods
setExpectedRemoveAttribute(String) and verify(), is good for
testing HOW things are done but it does not offer the
possibility to design robustness tests with this state-
modeling approached. The tests would have to be changed in
order to check the second implementation, with all the
possibilities to mess up the test.
In short - My patch would add additional support for the
design of state-oriented robustness tests that does not care
for HOW things are done, as long as they are done. This is
enforced without interferring with the current
MockHttpSession that enables good tools for testing HOW
things are done.