1

I have a "final" class, in which I need to test private methods, tried the following way for the failure case to get (Exception) but getting error

[junit] Caused by: IllegalArgumentException: Cannot subclass final class class

How to resolve this error, can anyone please suggest

//final class
public final Class Test {

  //private constructor
  private Test(Events event) {
     //initialization
  }

  private JSONObject getReg() {
    return new JSONObject;
  }

  private State Updation(String macAddr) {
    try {
      return update(getReg(), PATH, macAddr);
    } catch (Exception e) {
      throw new JSONException(e);
    } 
  }

 }


 @PrepareForTest({Test.class})
 @RunWith(PowerMockRunner.class)
 public class TestClassTest {

 @Test(expected = Exception.class)
 public void UpdationInvalidTest() throws Exception {
   JSONObject jsonObj = new JSONObject();

   Test test = Whitebox.invokeConstructor(Test.class, event);

   Test testSpy = PowerMockito.spy(test);
   PowerMockito.doReturn(jsonObj).when(testSpy, "getReg");

   Whitebox.invokeMethod(test, "Updation", "00:00:00:00:00:00");
 }
}
mrs
  • 207
  • 2
  • 5
  • 13
  • waht is `Whitebox`and `PowerMockito` can you show this two class .this two class can't extends RebootDevice – wylasr Apr 27 '17 at 06:24
  • On which line do you get the exception? You seem to be doing the right things ([see this question](http://stackoverflow.com/questions/39171894/powermock-mockstatic-cannot-subclass-final-class)). – Erwin Bolwidt Apr 27 '17 at 06:41
  • At this line I got error like "[junit] Caused by: java.lang.IllegalArgumentException: Cannot subclass final class" RebootDevice rebootDeviceSpy = PowerMockito.spy(rebootDevice); – mrs Apr 27 '17 at 06:50
  • Where do you initialize the `event` variable? – JDC Apr 27 '17 at 06:51
  • Also there is this question that seems to describe your problem, are you using Robolectric? http://stackoverflow.com/questions/38060683/cannot-mock-spy-final-class-using-powermockito-spy – JDC Apr 27 '17 at 07:01
  • 1
    Possible duplicate of [How do I test a class that has private methods, fields or inner classes?](http://stackoverflow.com/questions/34571/how-do-i-test-a-class-that-has-private-methods-fields-or-inner-classes) – mrs Apr 27 '17 at 08:55
  • Is RobbotDevice your own class? If so: consider writing source code that is testable by nature. Instead of writing something that is hard to test; to then turn to all kinds of dirty tricks to test that. – GhostCat Apr 27 '17 at 09:09
  • Why do you need to test private methods in the first place? They're an implementation detail that shouldn't be exposed, not even for the purpose of testing. – biziclop Apr 27 '17 at 10:26

2 Answers2

3

As @Ivan says, you should mock a final class. You can accomplish this like so:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Test.class)
public class TestClassTest {   

    @Mock
    private Test test;

    @Test(expected = Exception.class)
    public void UpdationInvalidTest() throws Exception {
       JSONObject jsonObj = new JSONObject().put("status", 123)
                                            .put("update-time", 123);

       Mockito.when(test.getReg()).thenReturn(jsonObj);

    }
}
mrs
  • 207
  • 2
  • 5
  • 13
0

You are getting error when trying to create a spy on a final class. You should use another approach to accomplish this - using mocks as described here: https://github.com/powermock/powermock/wiki/MockFinal:

Ivan Pronin
  • 1,768
  • 16
  • 14
  • I did a quick local test and the creation of a spy of a final class actually worked for me. – JDC Apr 27 '17 at 07:03