I need to mock a public, non-static method of an object.
The problem is that I ca'nt create a mock object, because this object is created directly in the code.
I have tried spying the class using PowerMockito.spy() and PowerMockito.when(...) but it didn't work (maybe its because PowerMockito.when only works for static and private methods)
For example, suppose I need to test this:
...
myClass anObject = new myClass();
anObject.aMethod();
...
How could I mock the call anObject.aMethod() ??
I guess I need to spy myClass, but it didn't work..
Use dependency injection.
In simplest case, just pass the factory object to the method that creates your object, and then spy that factory.
Other way of doing this is to pass the factory to the constructor of your object.
It's likely best to refactor your code to use dependency injection.
But a quick google suggests that you can actually stub the constructor in PowerMockito. See javadoc for whenNew.
I can't vouch for it as I haven't used PowerMockito, but this looks like it should allow you to make your constructor call return a mock object.
Related
I have a few 3rd parties static util methods in my project, some of them just pass or throw an exception. There are a lot of examples out there on how to mock a static method using PowerMock but Junit5 doesn't support PowerMock, which has a return type other than void. But how can I mock a static method that returns void to just "doNothing()"?
Don't mock it. From your minimal description, you could replace the usage sites with Consumer and provide a mock of that. (You can even initialize the fields with method references to the static methods and just have setter methods to override them.)
However, the fact that the class under test calls these static methods is usually just an implementation detail that the test shouldn't care about, only checking observable behavior.
Build a wrapper class on it, call the wrapper method, and you can have a different wrapper in your test if you can do behavior differently or have the wrapper to call a class/method can be mocked ,
When I put the #Mocked annotation on a object which has only constructor with parameters, will this object be initiated rightly?
When I put the #Mocked annotation on a object which has only constructor with parameters, will this object be initiated rightly?
No.
A mock will be created that has the same interface. That means it will have the same public methods and if the test class is in the same package it will also have the same protected and package private methods accessible.
This mock will not invoke the real methods of the mocked class (unless you configure it so).
This means that for every method that is expected to be called by your code under test (cut) and that has a return value defined you have to configure your mock so that is returns a value your cut shall work with in that particular test.
This configurable return values and the verify capabilities of the mocks are the reason why we use mocking frameworks.
Attention
If you want to mock the call to a method which accesses a member initialized by the mocked classes constructor you have to use the form
doReturn(SOME_VALUE).when(mock).methodToBeCalledByYourCut();
because the form
when(mock.methodToBeCalledByYourCut()).thenReturn(SOME_VALUE);
will raise a NullPointerException in that special case.
My class under test is ClassA which in one of its private method uses a static factory (lets say CarFactory) method getCar(XXX xxx) which returns a Car.
Part of the CarFactory logic is to validate that the given xxx parameters meets some criteria.
I tried using Mockito like the following:
#Mock private Car mockForCar;
#Mock private XXX xxxMock;
...
when(CarFactory.getCar(xxxMock)).thenReturn(mockForCar);
But I get an exception regarding that xxxMock isn't valid by the CarFactory.
Why is the real getCar(xxx) method gets called and not the stubbed one?
Is there a better way doing this?
From the Mockito FAQ:
Can I mock static methods?
No. Mockito prefers object orientation and dependency injection over
static, procedural code that is hard to understand & change. If you
deal with scary legacy code you can use JMockit or Powermock to mock
static methods.
If you want to stub this using Mockito, you should make it non-static and inject the factory. And that's better OO design anyway.
I want to mock a class from other library using Mockito. I read that Mockito relies on specific (CGLIB provided I think) implementation of equals method. Unfortunately this outer class has equals() denoted with final modifier, and there is throwing exception in its body.
When I try to mock this class I always get exception from this method. CGLIB apparently doesn't get by with final, and real method is called.
Any ideas? What can I do, to mock this class using Mockito? Maybe other library will handle it?
[EDIT] quick explanation: I don't want to mock equals(), I check other methods. Problem is that mockito internally uses equals(), I don't know what for. As equals() is final, real method is called with exception throwing. I had hope that there is some setting in mockito "don't use equals()" :-)
Thanks for answers, I will read them closely tomorrow.
This matrix shows features supported by different frameworks:
External link to the matrix here.
According to this, only PowerMock and JMockit can mock final methods.
Mockito cannot mock final methods. Apparently PowerMock can though.
A hacky workaround could be to create a non-final method that delegates to the final equals method and mock that.
I believe that the steps to mock a final method with PowerMock and Mockito API would be: run your tests with the #RunWith(PowerMockRunner.class) then prepare the class you want to mock #PrepareForTest(ClassToBeMocked.class). After that, mock your object and use the when method to mock the equals method.
I think that it won't work if you do not use the PrepareForTest annotation in your test class.
public class SupportController{
public void disableUserAccount(String username) throws Exception {
UserAccount userAccount =
new UserAccount(Constants.SYSTEM, Constants.CONTAINER, username);
UserAccount.disableAccount();
}
}
How would i test that the useraccount created is disabled?
I would suggest using Mock Objects.
Besides that, you can check the JUnit FAQ, where you can find a section about testing methods that return void.
Often if a method doesn't return a value, it will have some side
effect. Actually, if it doesn't return a value AND doesn't have a side
effect, it isn't doing anything.
There may be a way to verify that the side effect actually occurred as
expected
There are three basic solutions:
Use a factory class that can be mocked
Use PowerMock which can mock calls to constructors
Update the class to use a default scope or protected scope factory method which could be overridden in a test env.
PowerMock does not always play well with other runners (for example SpringJUnit4TestRunner). I usually avoid it for this reason and the fact that it modifies the compiled code.
The overridable factory method is another option. To do this you must extend the class and override the factory method. This means that the test is running against an instance of the class under test that is not actually the class under test but a testable subclass. This has test-smell to me so I tend to avoid it where possible.
The factory class method is my preferred solution. Pass in a Factory class that be default creates the UserAccount. In your test provide a mocked (I use Mockito) version of the factory.