powermock / powermock

PowerMock is a Java framework that allows you to unit test code normally regarded as untestable.
Apache License 2.0
4.15k stars 586 forks source link

Mocking JRE classes problem - mocking java.lang.Math #332

Closed johanhaleby closed 9 years ago

johanhaleby commented 9 years ago

From michal.r...@gmail.com on February 03, 2011 16:39:14

Why mocking of jre (system) classes works different than mocking of other (non jre) ?

1.I am testing MathUserr class. MathUserr calls static method OtherClass.myRandom(). 2.To mock OtherClass.myRandom() i need to: 2.1. add @PrepareForTest({ OtherClass.class}) annotation 2.2. call PowerMockito.mockStatic(OtherClass.class); 2.3. declare stubbing: when(OtherClass.myRandom()).thenReturn(2.0); 3.Now if class under test (MathUserr) calls OtherClass.myRandom(), it gets 2.0d value.

OK... it is clear. but now I describe the way, we mock JRE's java.lang.Math class.

1.I am testing MathUserr class. MathUserr calls static method Math.random(); 2.To mock Math.random() i need to: 2.1. add @PrepareForTest({ MathUserr.class}) annotation (WOOW, why MathUserr instead of Math???) 2.2. call PowerMockito.mockStatic(Math.class); 2.3. declare stubbing: when(Math.random()).thenReturn(2.0); 3.Now if class under test (MathUserr) calls OtherClass.myRandom(), it gets 2.0d value.

Everything in the same way, except of point 2.1.

Why it works in this way ? Is it documented ? Thanks in advance for any information :)

Source code that I am desribing: #############################################SOURCE CODE START#### package tp.check;

import static org.junit.Assert.; import static org.mockito.BDDMockito.;

import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class) @PrepareForTest({ OtherClass.class, MathUserr.class }) public class StaticTests { @Test public void mockMyStaticMethod() throws Exception { // given MathUserr u = new MathUserr(); PowerMockito.mockStatic(OtherClass.class); when(OtherClass.myRandom()).thenReturn(2.0);

    // when
    double fromOther = u.myClassRandom();

    // then
    assertEquals(2.0, fromOther, 0.0001);
}

@Test
public void mockJreLibStaticMethod() throws Exception {
    // given 
    MathUserr u = new MathUserr();
    PowerMockito.mockStatic(Math.class);
    when(Math.random()).thenReturn(2.0);

    // when
    double fromOther = u.jreRandom();

    // then
    assertEquals(2.0, fromOther, 0.0001);
}

}

class MathUserr{ public double jreRandom(){ return Math.random(); }

public double myClassRandom(){
    return OtherClass.myRandom();
}

}

class OtherClass{ public static double myRandom(){ return 22.0; // ;) } }

#############################################SOURCE CODE END####

    I attach my env (from maven pom) below:

    \<dependency>
        \<groupId>junit</groupId>
        \<artifactId>junit</artifactId>
        \<version>4.8.1</version>
        \<scope>test</scope>
    \</dependency>
    \<dependency>
        \<groupId>org.mockito</groupId>
        \<artifactId>mockito-all</artifactId>
        \<version>1.8.5</version>
        \<scope>test</scope>
    \</dependency>
    \<dependency>
        \<groupId>org.powermock</groupId>
        \<artifactId>powermock-module-junit4</artifactId>
        \<version>1.4.6</version>
        \<scope>test</scope>
    \</dependency>
    \<dependency>
        \<groupId>org.powermock</groupId>
        \<artifactId>powermock-api-mockito</artifactId>
        \<version>1.4.6</version>
        \<scope>test</scope>
    \</dependency>

Original issue: http://code.google.com/p/powermock/issues/detail?id=312

johanhaleby commented 9 years ago

From johan.ha...@gmail.com on February 04, 2011 01:32:48

This is because it's impossible to byte-code manipulate Java System classes such as Math. It's documented here: https://code.google.com/p/powermock/wiki/MockSystem http://blog.jayway.com/2009/05/17/mocking-static-methods-in-java-system-classes/

johanhaleby commented 9 years ago

From johan.ha...@gmail.com on February 04, 2011 01:33:04

Status: WontFix

johanhaleby commented 9 years ago

From michal.r...@gmail.com on February 04, 2011 01:38:32

thanks a lot for your reply.