Monday 15 August 2011

java - Mockito: Test a method that takes string of long length -



java - Mockito: Test a method that takes string of long length -

my method returns exception if input string (stringbuilder in case) longer 2048 characters. since cannot mock final classes using mockito, can tells me how unit test this.

one way pass string long seems stupid. there easy way test this?

it's credit mockito's developers passing mock seems easier creating real string. however, creating real string still smartest alternative test.

you correctly noted string final, mockito's can't utilize proxies or bytecode generation silently create subclass it. instead forced utilize powermock, rewrite bytecode of class-under-test using custom classloader utilize mocked string.length() instead of actual implementation. either way, that's awful lot of work mimic simple string, , may take more test time , memory alternative.

even if string weren't final, you'd still writing brittle test, because you'd (presumably) mocking subset of string. in hypothetical, write:

when(mockstring.length()).thenreturn(2048);

but then, 1 day, implementation turns to:

public boolean isstringvalid(string input) { // handle unicode surrogate pairs. homecoming input.codepointcount(0, input.length()) <= 1024; // not 2048 }

...and test erroneously passes because mockito sees unmocked codepointcount , returns default int homecoming value, 0. 1 of reasons tests using incomplete mocks less-resilient , less-valuable tests using real objects.

but finish mocks? mock codepointcount, , on. taken logical conclusion, imagine mock string object advanced, correctly returns value absolutely phone call give it. @ point you've reimplemented string inside-out, @ expense of readability, , spent many engineering science hours reproducing 1 of most-tested, most-obvious implementations in java's history little reason. if anything, that seems pretty stupid me.

a few guidelines:

don't mock implementations don't own. mockito still bound final markings in implementations mocks, instance, mocking other types bad habit into. when other teams' implementation details break tests, that's bad sign.

don't mock objects when can utilize real, tested, authentic instance. there's reason mock in case, , doing create test unnecessarily-brittle.

in particular, don't mock info objects. rely on getfoo matching setfoo, instance, , may rely on equals , hashcode working. in case, well-designed info objects don't have external dependencies.

mock interfaces instead of implementation classes when can. insulates against implementation details alter way mocks work.

if find info object makes service calls, or uses resources aren't testing, remember can refactor classes improve testability—such extracting service methods separate well-defined classes, or extracting interfaces , create custom reusable test doubles. tests should first-class users of classes, , it's prerogative alter classes command (or wrap classes don't control) sake of testability. i've found makes classes easier utilize in production.

java unit-testing mockito

No comments:

Post a Comment