Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock Runtime.getRuntime()?

Tags:

Can anyone make any suggestions about how best to use EasyMock to expect a call to Runtime.getRuntime().exec(xxx)?

I could move the call into a method in another class that implements an interface, but would rather not in an ideal world.

interface RuntimeWrapper {
    ProcessWrapper execute(String command) throws IOException;
}

interface ProcessWrapper {
    int waitFor() throws InterruptedException;
}

I was wondering if anyone had any other suggestions?

like image 936
Rich Avatar asked Feb 13 '10 14:02

Rich


People also ask

How do you do a mock runtime?

getRuntime(). exec() you could "mock" the script/program/etc. it's supposed to be calling. Instead of passing the real command-line string into exec() , write a test script and execute it instead.

What is runtime getRuntime exec in Java?

Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running. The current runtime can be obtained from the getRuntime method.


2 Answers

Your class shouldn't call Runtime.getRuntime(). it should expect a Runtime to be set as its dependency, and work with it. Then in your test you can easily provide a mock and set it as a dependency.

As a sidenote, I'd suggest watching this lecture on OO Design for testability.

Update: I didn't see the private constructor. You can try using java bytecode instrumentation in order to add another constructor or make the constructor public, but that might turn out to be impossible as well (if there are some restrictions on that class).

So your option is to make a wrapper (as you suggested in the question), and follow the dependency-injection approach.

like image 191
Bozho Avatar answered Oct 11 '22 09:10

Bozho


Bozho above is IMO the Correct Solution. But it is not the only solution. You could use PowerMock or JMockIt.

Using PowerMock:

package playtest;

public class UsesRuntime {
    public void run() throws Exception {
        Runtime rt = Runtime.getRuntime();
        rt.exec("notepad");
    }
}


package playtest;

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

import static org.powermock.api.easymock.PowerMock.*;
import static org.easymock.EasyMock.expect;

@RunWith(PowerMockRunner.class)
@PrepareForTest( { UsesRuntime.class })
public class TestUsesRuntime {

    @Test
    public void test() throws Exception {
        mockStatic(Runtime.class);
        Runtime mockedRuntime = createMock(Runtime.class);

        expect(Runtime.getRuntime()).andReturn(mockedRuntime);

        expect(mockedRuntime.exec("notepad")).andReturn(null);

        replay(Runtime.class, mockedRuntime);

        UsesRuntime sut = new UsesRuntime();
        sut.run();
    }
}
like image 39
Michael Lloyd Lee mlk Avatar answered Oct 11 '22 10:10

Michael Lloyd Lee mlk