简体   繁体   中英

Call constructor with and without parameter with PowerMockito

I'm struggling try to understand how PowerMockito works.

What I'm trying to test, is a method that call two method of the same class, and also a method on a joda DateTime class, who, as you know, is a final class, so it's impossible to mock with Mockito. That's why I using (after hours of investigation) Powermockito.

I'm using @RunWith(PowerMockRunner.class) and @PrepareForTest with the two classes (the one being tested and the joda.time.DateTime ), and my setUp() looks similar to this

target = new ClassToBeTested();
DateTime TODAY = new  DateTime(2016, 8, 6, 0, 0, 0, 0);
PowerMockito.whenNew(DateTime.class).withNoArguments().thenReturn(TODAY);

This four lines of code represent hours of investigation, test and errors, but they worked: inside the method of 'target' that I need to test, when I create a DateTime object with no arguments, so I could use it to know the current day, it return the TODAY object. The problem is that, inside that method, I need also to create another couple of DateTime Objects, and initialized them with difference dates (the logic of the method involves compare this two dates with the current day and take actions), so, I thought that the solution could be

DateTime TODAY = new  DateTime(2017, 8, 17, 0, 0, 0, 0);
DateTime createdOn = new DateTime(2016, 7, 6, 10, 0, 0, 0);
DateTime recordedOn = new DateTime(2016, 7, 7, 12, 20, 0, 0);
PowerMockito.whenNew(DateTime.class).withNoArguments().thenReturn(TODAY);
PowerMockito.whenNew(DateTime.class).withAnyArguments().thenReturn(createdOn, recordedOn);

But when I tried, I received createdOn instead of TODAY in the DateTime constructor with no parameters, and then the correct createdOn and recordedOn . It's like if the line withAnyArguments invalidate the withNoArguments

To show you more clearly what I tried to do, this is how looks like the method to be tested (only the important part)

DateTime today = new DateTime(); //To know current day, I was hoping that the withNoArgument take care of this returning TODAY. But it really received createdOn        
DateTime createdOnDay = new DateTime(this.getDateCreated()); it received , createdOnd       
DateTime recordedOnDay = new DateTime(this.getDateRecorded());
// It received recordedOn. 

Can someone point me what I'm doing wrong?

Regards

Side remark: it's highly discouraged to use PowerMockito "mockNew", you should always when possible refactor the code under test to allow testing.


With this:

Foo :

package so36119627;

public class Foo {

    private final String bar;

    public Foo(String bar) {
        this.bar = bar;
    }

    public Foo() {
        this("hello");
    }

    public String getBar() {
        return bar;
    }
}

Bar :

package so36119627;

public class Bar {
    public String bar() {
        return new Foo().getBar() + " / " + new Foo("world").getBar();
    }
}

the following test runs fine and do what you want:

package so36119627;

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

import static org.junit.Assert.assertEquals;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Foo.class, Bar.class})
public class BarTest {
    @Test
    public void test1() throws Exception {
        assertEquals("hello / world", new Bar().bar());
    }

    @Test
    public void test2() throws Exception {
        // do not inline foo1 and foo2, because of powermock
        final Foo foo1 = new Foo("with arg");
        final Foo foo2 = new Foo("no arg");
        PowerMockito.whenNew(Foo.class).withArguments(Matchers.anyString()).thenReturn(foo1);
        PowerMockito.whenNew(Foo.class).withNoArguments().thenReturn(foo2);

        assertEquals("no arg / with arg", new Bar().bar());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM