Mocking a private field in a servlet filter

Is it possible to make fun of (currently using Mockito, maybe another test lib) the 'sf' field in the class shown below:

public class SomeFilter implements Filter { private Logger log = Logger.getLogger(getClass()); private SomeField sf = new SomeField(); @Override public void init(FilterConfig fc) throws ServletException { log.info(""); } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain fc) throws IOException, ServletException { fc.doFilter(request, response); } @Override public void destroy() { log.info(""); } } 

If so, how?

+4
source share
4 answers

I would have the desire to make the field either protected or package-private , and then enter the layout in your test, for example:

 final SomeField sf = mock(SomeField.class); someFilter.sf = sf; 

Otherwise, you can provide a constructor for entering the layout:

 ... public SomeFilter() { this(new SomeField()); } public SomeFilter(SomeField sf) { this.sf = sf; } ... 

Then in your test, you could pass the layout like this:

 final SomeField sf = mock(SomeField.class); SomeFilter someFilter = new SomeFilter(sf); 
+2
source

Consider PowerMock with some great features, including some integration with the Mockito framework

Consider this example to bypass encapsulation and access a private field, for example below

 String sf = Whitebox.getInternalState(o, "sf", String.class, B.class); Whitebox.setInternalState(o, "sf", "XXX", B.class); 

Also consider (from the last link):

All these things can be achieved without using PowerMock, it is just a normal reflection of Java. However, reflection requires a lot of boiler room code and can be error prone, and therefore PowerMock provides you with these utility methods. PowerMock gives you the choice of whether to reorganize your code and add getter / setter methods to check / change the internal state or use its utility methods to perform the same action without changing the production code. It is for you!

+4
source

Yes. In your Test class, you can use ReflectionTestUtils from the Spring Framework

http://static.springsource.org/spring/docs/2.5.5/api/org/springframework/test/util/ReflectionTestUtils.html

call the setField method as follows:

 SomeFilter filter = new SomeFilter(); SomeField field = Mockito.mock(SomeField.class); ReflectionTestUtils.setField(filter , "sf", field); 

You can wave an object in a test case, as usual.

If you cannot import the Spring Framework, it is not too difficult to directly use Java reflection to do the same.

+3
source

You can use PowerMock to mock the constructor of the SomeField class. From the doc:

Layout of the construction of new objects

  • Use the @RunWith(PowerMockRunner.class) annotation @RunWith(PowerMockRunner.class) on the test case level class. Use the @PrepareForTest(ClassThatCreatesTheNewInstance.class) annotation at the class level of the test case.
  • Use PowerMock.createMock(NewInstanceClass.class) to create a mock object of the class that should be built (call it mockObject).
  • Using PowerMock.expectNew(NewInstanceClass.class).andReturn(mockObject) until you expect a new construction of an object of type NewInstanceClass.class, but returns a layout instead.
  • Use PowerMock.replay(mockObject, NewInstanceClass.class) to change the exact object and class to play mode, alternatively use PowerMock.replayAll() .
  • Use PowerMock.verify(mockObject, NewInstanceClass.class) to change the layout of the object and the class to check the mode, alternatively use PowerMock.verifyAll() .

If you want to use powermock with Mockito syntax , it looks like this:

 whenNew(MyClass.class).withNoArguments().thenThrow(new IOException("error message")); 
+1
source

All Articles