My class Under Test access Main itself (Main.doSomething)
I would like to mock Main class to avoid setting up the whole process with all the hasltle
how can I do so?
I am using Powermock with Mockito.
Main is not a reserved word for a class in Java. It means you can test like any other class. It depends if doSomething is static and/or final or not.
Provided that having to mock static methods is a bad practice (your method shouldn't be static if it is supposed to be mocked: if the class is difficult to test – refactor the class -- http://monkeyisland.pl/2008/01/14/mockito/).
Nevertheless, here is how you do it with powermock:
PowerMockito.mockStatic(Main.class);
PowerMockito.when(Main.doSomething()).thenReturn(something);
Here the documentation: http://code.google.com/p/powermock/wiki/MockStatic
For mocking static members do:
Whitebox.setInternalState(Main.class, doSomething);
A more powerful Mocking Framework is JMockit. It gives enhanced mocking and stubbing functionality.
CheckOut: http://code.google.com/p/jmockit/
Related
I am learning now about the topic Unit Testing in Java and interesting came to me a question that if we can test if a method was called without using Mock or Spy from Mocking Framework.
I mean for example if I have a simple class like
class A {
public void method1(){}
}
How can I test if method1 was called from an instance a?
Do you think is it possible and how can I get that?
Thank you very much
Put this inside method1()
System.out.println("[methodname] has been executed :)");
In your test class you may inherit from A and override method1 and implement counting behaviour i.e. and use it for your test case
I'm reading some test code that calls mockStatic(MyClass.class), but MyClass is neither static nor does it contain static methods.
Are there other benefits of using mockStatic()?
Not sure if related, but PowerMock is also used in the test code.
I cannot comment so I just reply here..
According to its latest documentation, Mockito doesnt have mockStatic(), so I think this comes from PowerMock. You can go in to the method declaration to see at least the method comes from which module.
For Powermock, the class inside mockStatic() doesnt have to be static class. The goal of mockStatic is to mock the static method. See here: https://code.google.com/p/powermock/wiki/MockStatic
The code has something like
Speed speed = readSpeed(Point A, Point B);
isOverLimit = limitCheck.speedCheck(speed);
How do I use mockito for read speed?
Mockito.when(readSpeed(0, 0).then...
suppose should I use the class object to call this?
Mockito effectively works by creating individual subclasses of objects that delegate every overridable implementation to the mock framework.
Consequently, you can't use Mockito mock your method (readSpeed) for all instances at once or instances created in your system under test, nor mock any static or final methods. If readSpeed is any of those, or need to be mocked on an instance you don't touch in your test, Mockito will not work for you; you'll need to refactor, or use PowerMockito (which quietly rewrites your system under test to redirect constructors, final calls, and static calls to Mockito's framework).
If readSpeed is a public non-final instance method on your system under test, then you can mock it, and that'd be called a partial mock of your component. Partial mocks can be useful, but can also be considered "code smells" (as mentioned in the Mockito documentation): Ideally your test class should be an atomic unit to test, and mocking should happen for the dependencies around your system under test rather than your test itself. Otherwise, you could too easily test the spec or test the mocking framework rather than testing your component.
Though the better thing to do would be to split the class into smaller interconnected components, you can use partial mocking in Mockito like this:
#Test public void componentChecksSpeed() {
YourComponent yourComponent = Mockito.spy(new YourComponent());
// Use doReturn, because the when syntax would actually invoke readSpeed.
doReturn(65).when(yourComponent).readSpeed(any(Point.class), any(Point.class));
yourComponent.run();
}
I have mocked a static method of a class using Powermock in my test class. The problem I face is that this static method is not called directly in my test class, but in some other class. Here is the skeleton:
#Test public void myTest() {
PowerMockito.mockStatic(MyClassWithStaticMethod.class);
PowerMockito.when(MyClassWithStaticMethod.staticMethod()).thenReturn("...");
List<String> details = MyHelperClass.getDetails();
...
...
}
Now MyHelperClass.getDetails calls the method that needs to be mocked as it is dependent upon a service.
MyHelperClass.java
public static List<String> getDetails() {
...
...
MyObj obj = MyClassWithStaticMethod.staticMethod(); //This needs to return mocked value
...
...
}
Is there a way to pass the mocked object to the helper class? PowerMockito.mockStatic returns void, where as PowerMockito.mock doesn't mock the static methods. So I am not able to figure out how to pass the mocked object to the helper class getDetails() method.
PowerMock isn't really capable of what you're willing to achieve. There's another mocking framework, that can mock literally almost everything by instrumenting the bytecode - JMockit
As for your problem - perhaps that would help
Just a simple note regarding static methods - since this kind of methods is harder to stub and since stubbing them can potentially affect other tests, I recommend adding unit tests for them and relying on those tests instead of trying to make sure the method is called.
The reason I'm advocating on this approach is that static methods should consist only of utility methods, which once tested can be relied upon. And also checking method calls always introduces coupling between your code and the unit tests, resulting in headaches when thinking about refactoring, as application code refactoring leads to lots of unit tests needing changes.
I would like to write some state based tests using JMockit to mock up CSVRecord. The problem is that CSVRecord is final (which means I have to use a mocking framework like JMockit) and CSVRecord's constructor has package private visibility.
Since it is package private, I can't call new CSVRecord(arg, arg, ...), which means I can never I instantiate my mock.
Its parent, CSVParser, is the only class that can create an instance.
Does JMockit have a way to deal with this scenario?
note: JMockit or Mockito are the only frameworks we use on this project. No other framework will be acceptable. My preference is to use a MockUp.
It sounds more like CSVRecord isn't a good candidate for mocking. If possible, tests targetting another public class which uses it internally would be preferable.
Otherwise, JMockit provides a Deencapsulation class with newInstance methods.
As a side note, Mockito only supports behavior-based tests; JMockit provides "mock-ups" (MockUp), but it's not the same as writing a pure state-based black box test.
If it is just a matter of calling the private constructor, then yes, JMockit has tools to deal with that. See the tutorial
Use:
ConstructorReflection.newInstance
in newer versions of Jmockit.