15

I'm trying to learn the ins and outs of various mocking libraries and PowerMock(specifically the EasyMock extension) is next on the list. I'm attempting to mock a constructor and the examples provided don't have the same response when I try to replicate them. As far as I can tell, it never mocks the constructor and just proceeds as if it were normal.

This is the test class:

@RunWith(PowerMockRunner.class)
@PrepareForTest({Writer.class})
public class FaultInjectionSituationTest {

    @Test
    public void testActionFail() throws Exception {
        FaultInjectionSituation fis = new FaultInjectionSituation();
        PowerMock.expectNew(Writer.class, "test")
           .andThrow(new IOException("thrown from mock"));
        PowerMock.replay(Writer.class);
        System.out.println(fis.action());
        PowerMock.verify(Writer.class);
    }

}

I've tried replacing the "test" with an EasyMock.isA(String.class), but it yielded the same results.

This is the FaultInjectionSituation:

public class FaultInjectionSituation {

    public String action(){
        Writer w;
        try {
            w = new Writer("test");
        } catch (IOException e) {
            System.out.println("thrown: " + e.getMessage());
            return e.getLocalizedMessage();
        }
        return "returned without throw";
    }
}

The "Writer" is nothing more than a shell of a class:

public class Writer {
    public Writer(String s) throws IOException {
    }

    public Writer() throws IOException{
    }
}

When the test is run, it prints out "returned without throw", indicating the exception was never thrown.

rrufai
  • 1,475
  • 14
  • 26
AdamSpurgin
  • 951
  • 2
  • 8
  • 28

2 Answers2

29

You need to prepare the class that is calling the constructor as well, so PowerMock knows to expect a mocked constructor call. Try updating your code with the following:

@RunWith(PowerMockRunner.class)
@PrepareForTest({Writer.class, FaultInjectionSituation.class})
public class FaultInjectionSituationTest { 
 // as before
}
rrufai
  • 1,475
  • 14
  • 26
2

You need to first create a mock object:

Writer mockWriter = PowerMock.createMock(Writer.class)
PowerMock.expectNew(Writer.class, "test").andReturn(mockWriter)
fo_x86
  • 2,583
  • 1
  • 30
  • 41
  • I'm not trying to create a mock object, I'm attempting to intercept the constructor and throw an exception in its place. the "more features" section of [this page](http://code.google.com/p/powermock/wiki/MockConstructor) is what I'm aiming for. – AdamSpurgin Sep 10 '12 at 23:26
  • 1
    sorry, I see what you are trying to do. I just tried your code on JUnit 4 and it prints out "thrown from mock" (what you'd expect). Are you using TestNG by any chance? I'm not familiar with TestNG but when I ran it using TestNG, I got "returned without throw" – fo_x86 Sep 11 '12 at 03:00
  • I'm using Junit4. I can't think of anything that would cause it to not work. – AdamSpurgin Sep 11 '12 at 16:04
  • I don't think there's anything wrong with your code (as I was able to get the desired output). How are you running JUnit? From an IDE or commandline? – fo_x86 Sep 11 '12 at 18:37
  • I've tried both. I'm handing it to a coworker to run on their machine, maybe that will help illuminate the issue. – AdamSpurgin Sep 11 '12 at 20:38