Unit-Test mit EasyMock – Parameter-Check
Kürzlich habe ich ein Bugfix in einer Service-Klasse gemacht, der verhindern sollte, daß ein String länger als 64 Zeichen wird. Da es sich an dieser Stelle um ein Label gehandelte, konnte ich es mittels der Apache-Commons-Klasse StringUtils kürzen. Bei der Gelegenheit wollte ich diesen Aspekt im Unit-Test berücksichtigen. Die Frage die sich jedoch stellte: “Wie komme ich an einem im Service erzeugten Parameter mit dem wiederum ein weiterer Service aufgerufen wird?”
Ausschnitt des zu testenden Services:
public UserAccount storeUserAccount(UserContext userContext, UserAccount userAccount){ Assert.notNull(userContext, "userContext != NULL"); Assert.notNull(userAccount, "userAccount != NULL"); . . . // not accessable from outside String x = calcInInternalMethod(); x = StringUtils.abbreviate(username, 64); SpecialOject so = delegatedService .doSomething(userContext, x); . . . return userAccount; }
Ich habe keinen EasyMock-Matcher gefunden der die String-Länge prüft. EasyMock unterstützt mit dem Interface IArgumentMatcher jedoch das man einen eigenen Matcher schreiben kann. Der folgende “Matcher” kann die String-Länge prüfen.
import org.easymock.EasyMock; import org.easymock.IArgumentMatcher; /** * Matcher for max-String-length-check with EasyMock. * * @author blog.analysisfreaks.de */ public class StringLengthMatcher implements IArgumentMatcher{ private int size; private int actualLength; /** * Private Constructor. * @param size */ private StringLengthMatcher(int size) { this.size = size; } /** * Matcher that checks the max-length of a {@link String} * @param size (>0) * @return */ public static String notLongerThan(int size){ EasyMock.reportMatcher(new StringLengthMatcher(size)); return null; } /** * {@inheritDoc} */ public void appendTo(StringBuffer buffer) { buffer.append("notLongerThan(") .append(size).append(") size exceeded with lenght == ") .append(this.actualLength).append("!"); } /** * {@inheritDoc} */ public boolean matches(Object argument) { if(argument==null) return false; actualLength = argument.toString().length(); boolean ok = actualLength<=size; return ok; } }
Der Unit-Test sieht dann wie folgt aus:
@Test(description = "test with normal data") public void testStoreUserAccount() { . . . EasyMock.expect(delegatedService.doSomething( (String)EasyMock.anyObject(), StringLengthMatcher.notLongerThan(64))) .andReturn(null); . . . EasyMock.replay(x,y,z,delegatedService); UserAccount storedUserAccount = benutzerService.storeUserAccount(userContext, userAccount); EasyMock.verify(x,y,z,delegatedService); }