How can I surpass or skip a method using JUNIT? - java

I have a block of code for which I need to test .Lets say
Class MainClass{
public void startProcess() {
----Some Logic to generate fileName;
uploadFile(fileName);
}
private static void uploadFile(String key) {
fileUpload();
deleteFile();
}
}
I want to write a JUNIT test which will call startProcess but either skip the uploadFile line or just ignore any lines present in uploadFile method .
I tried to use powerMock but it doesnt work . Below is my code
#RunWith(PowerMockRunner.class)
#PrepareForTest(MainClass.class)
public class MainClassTest {
#Test
public void teststartProcess() throws Exception {
processor=PowerMock.createPartialMock(MainClass.class,"uploadFile");
PowerMock.expectPrivate(processor , "uploadFile", "xyz").andAnswer(
new IAnswer<Void>() {
#Override
public Void answer() throws Throwable {
System.out.println("Invoked!");
return null;
}
}).atLeastOnce();
}
}
But it does't override the method uploadFile to just print invoked . It calls fileUpload and deleteFile instead of just skipping the lines and print invoke .
My basic goal is to mock the method uploadFile to just print
private void uploadFile(String key) {
System.out.println("Invoked");
}
I know it's possible using Mockito but we can use either PowerMock or EasyMock .

Instead of trying to go the way with over complicated tests you should consider to refactor your code so that it is testable. From what you provided I would move the file functionality to another class.
something like this:
public class MainClass {
private final FileUploader fileUploader;
public MainClass(FileUploader fileUploader) {
this.fileUploader= fileUploader;
}
public void startProcess() {
fileUploader.uploadFile(fileName);
}
}
With this refactoring you gain the possibility to use plain mocking for the test:
String fileName = "foo";
FileUploader fileUploader = mock(FileUploader.class);
MainClass classUnderTest = new MainClass(fileUploader);
classUnderTest.startProcess();
verify(fileUploader, times(1)).uploadFile(fileName);
An additional benefit is that testing the fileUploader becomes also easy. As you can see I also got rid of all the complicated Partial mocking and private testing.

You have to change the mock object to replay mode before calling the method under test and you have to tell Powermock to work on a static method:
mockStaticStrict(MainClass.class,method(MainClass.class, "uploadFile"));
PowerMock.replay(processor);
processor.startProcess();
See Mocking private methods for further information on this.
I highly suggest to refactor this code and make it testable.

Related

How can I test if a method was called on an object created inside the method to be tested

Is it possible to test that the "innerMethod" was called without modifying the Class class?
I need to make a unit test in a separate class both scenario of the "someCondition".
The problem is that the method is void so I cannot make use of the return type. The only way would be to check if the "innerMethod" was called.
I was thinking to use Mokito verify but this method is called inside a method on an object created at runtime.
Any suggestion is most welcome.
public class Class {
public void outerMethod(outerObj) {
if(someCondition) {
Object innerObj = new Object();
innerObj.innerMethod(outerObj);
} else {
//other code
}
}
You can achieve that with the use of Mockito::times and Mockito::verify methods.
test setup would be as follows:
#InjectMocks
private SomeService service;
#Mock
private SomeHelper helper;
and then test that some method from the helper has been involved in the following manner:
#Test
public void testInnerHasBeenCalledOnce() throws Exception {
service.outherMethodName(someParam);
Mockito.verify(helper, Mockito.times(1)).innerMethodName(someParamSecond);
}

JMockit: Overriding #Mocked class

I have an internal StreamGobbler class that has 7 methods in it.
I'm looking for a quick way to mock all the methods by default, but override one method named getOutput() (e.g. Partial Mocking).
(full code not shown for clarity)
public class StreamGobbler extends Thread
{
public String getOutput()
public void run()
}
What I would like is to use something like the #Mocked annotation in combination with MockUp to partially mock the getOutput method, but retain all the "default" mocking code on all the other methods. In the docs on partial mocking, it makes the point that if you use MockUp, all non #Mock methods retain their normal functionality. Sometimes that is great, but that isn't what I want in this case.
This is similar to the question JMockit: #Mocke and MockUp combination in the same test, but I can't get away with just looking at method counts.
If I have a test setup like this:
#Test
public void execute(#Mocked StreamGobbler sg)
{
new MockUp<StreamGobbler>()
{
String type = null;
#Mock
void $init(String type)
{
this.type = type;
}
#Mock
String getOutput()
{
if ("OUTPUT".equals(type))
{
return "test output";
}
else
{
return "";
}
}
}
}
I get this error java.lang.IllegalArgumentException: Class already mocked
If I try to add the #Override annotation in the MockUp, it doesn't help (and Eclipse complains about it)
What is the best way to handle this? Use a static class outside this test method?
Using JMockit 1.17, and TestNG
In summary, how do I get every method in StreamGobbler mocked (as with #Mocked), but partially override one method (without manually doing it myself inside the MockUp?)
Full example code which meets the given constraints:
public static class StreamGobbler extends Thread {
public StreamGobbler(String type) {}
public String getOutput() { return null; }
#Override public void run() {}
}
public static class TestedClass {
public String doSomething() throws InterruptedException {
StreamGobbler sg1 = new StreamGobbler("OUTPUT");
sg1.start();
StreamGobbler sg2 = new StreamGobbler("ERROR");
sg2.start();
sg1.join(5000);
sg2.join(5000);
String output1 = sg1.getOutput();
String output2 = sg2.getOutput();
return output1 + '|' + output2;
}
}
#Test
public void useStreamGobbler(#Mocked StreamGobbler sg) throws Exception {
new Expectations() {{
new StreamGobbler("OUTPUT").getOutput(); result = "test output";
new StreamGobbler("ERROR").getOutput(); result = "";
}};
String output = new TestedClass().doSomething();
assertEquals("test output|", output);
}
Firstly, since you are creating an anonymous subclass of the MockUp class, using the #Override annotation would certainly be inappropriate. Those methods that you are providing do not belong to the MockUp class, but the generic you are providing.
Later on during runtime, (through some impressive process (based on what I read here, I'm assuming AOP)) the instance you create in this class will then use your provided method signatures instead of its own.
After reading the API on the Mock class more thoroughly as well as getting some information from JMockit's Getting Started page, I think you're issue lies in a different area entirely. If you have other test methods, they will be interfering with this method.
The error you are getting is saying: "There is already an instance of MockUp declared for the type StreamGobbler, and by calling the Mocked annotation in this test method's parameters and attempting to declare another instance of MockUp with the same generic, you are violating a JMockit stipulation."
I would check to see if you are creating an actual MockUp of StreamGobbler outside of the test method and if so (1) if you want to use it, don't redeclare another instance of MockUp in the method but continue to use the Mocked annotation or (2) if you do not want to use it and you want to re-declare a new instance of MockUp wrapping StreamGobbler, do not use the Mocked annotation in the test method's parameters but keep the MockUp instantiation.

GwtMockito: Is there a way to test Window.open()?

I would like to test that my call of Window.open(String) is with the correct URL (to download a file).
Is there any better way of doing it, besides using a partial mock, like this?
MySUT sut = Mockito.spy(new MySUT());
String expectedURL = "http://www.example.com";
doNothing().when(sut).openWindow(expectedURL);
sut.doSomethingThatOpensURL();
verify(sut).openWindow(expectedURL);
Where openWindow(String) is as simple as possible in MySUT:
void openWindow(String url) {
Window.open(url);
}
Does GwtMockito give you something to test methods that execute native javascript like Window.open(String)?
I suppose there is no ability to verify it using GwtMockito.
But I believe it's possible using PowerMock and EasyMock.
This mocking frameworks provide great flexibility to test static methods and 3rd party classes.
I've just created a simple example how you can test Window.open().
In my test case I'm just checking Window.alert(), for example.
#RunWith(PowerMockRunner.class)
#PrepareForTest(Window.class)
#SuppressStaticInitializationFor("com.google.gwt.user.client.Window")
public class SimpleTester {
/** Simple class for test. */
private class TestClass {
public void open(String url) {
Window.alert(url);
}
}
#Test
public void test() {
PowerMock.mockStatic(Window.class);
TestClass obj = new TestClass();
Window.alert("test");
EasyMock.expectLastCall();
PowerMock.replay(Window.class);
obj.open("test");
PowerMock.verify(Window.class);
}
}

How to Invoke a private method on a singleton (Enum style) in java?

Is there a way to invoke a private static method of an enumerated singleton? For example, say I have some legacy code that I need to test which has the following structure:
public enum Singleton {
INSTANCE;
private static double methodToTest() {
return 1.0;
}
public static String extremelyComplexMethod() {
methodToTest();
//Imagine lots more complex code here
return "";
}
}
How would I go about creating a class that tests methodToTest in isolation? I've tried reflection using Whitebox (included in PowerMock) but I've had no luck. Is there a way to do it?
I know that testing a private method directly is not the prefered method of doing things, but I want to know if its possible to test the private method directly. I tried to get the code to get recognized as java, but I was unsuccessful.
I was able to invoke the method try this following code
#RunWith(PowerMockRunner.class)
#PrepareForTest(Singleton.class)
public class MySingletonTest {
#Test
public void test() throws Exception{
Whitebox.invokeMethod(Singleton.class, "methodToTest");
}
}
Don't forget to add the Singleton class in PrepareForTest

How to mock static method in Java?

I have a class FileGenerator, and I'm writing a test for the generateFile() method that should do the following:
1) it should call the static method getBlockImpl(FileTypeEnum) on BlockAbstractFactory
2) it should populate variable blockList from the subclass method getBlocks()
3) it should call a static method createFile from a final helper class FileHelper passing a String parameter
4) it should call the run method of each BlockController in the blockList
So far, I have this empty method:
public class FileGenerator {
// private fields with Getters and Setters
public void generateBlocks() {
}
}
I am using JUnit, Mockito to mock objects and I've tried using PowerMockito to mock static and final classes (which Mockito doesn't do).
My problem is: my first test (calling method getBlockList() from BlockAbstractFactory) is passing, even though there is no implementation in generateBlocks(). I have implemented the static method in BlockAbstractFactory (returning null, so far), to avoid Eclipse syntax errors.
How can I test if the static method is called within fileGerator.generateBlocks()?
Here's my Test Class, so far:
#RunWith(PowerMockRunner.class)
public class testFileGenerator {
FileGenerator fileGenerator = new FileGenerator();
#Test
public void shouldCallGetBlockList() {
fileGenerator.setFileType(FileTypeEnum.SPED_FISCAL);
fileGenerator.generateBlocks();
PowerMockito.mockStatic(BlockAbstractFactory.class);
PowerMockito.verifyStatic();
BlockAbstractFactory.getBlockImpl(fileGenerator.getFileType());
}
}
I have no experience with PowerMock, but since you didn't get an answer yet I'm just been reading through the documentation to see if I can help you a bit on your way.
I found that you need to prepare PowerMock so that I knows which static methods it needs to prepare to be mocked. Like so:
#RunWith(PowerMockRunner.class)
#PrepareForTest(BlockAbstractFactory.class) // <<=== Like that
public class testFileGenerator {
// rest of you class
}
Here you can find more information.
Does that help?
Working example:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ClassStaticA.class, ClassStaticB.class})
public class ClassStaticMethodsTest {
#Test
public void testMockStaticMethod() {
PowerMock.mockStatic(ClassStaticA.class);
EasyMock.expect(ClassStaticA.getMessageStaticMethod()).andReturn("mocked message");
PowerMock.replay(ClassStaticA.class);
assertEquals("mocked message", ClassStaticA.getMessageStaticMethod());
}

Categories

Resources