mockito unit testing Wanted but not invoked: - junit

I have seen there are similar question already exist in SO , I tried all the solution , but couldn't fix my problem , as I am new to tdd
I have a class like this
public class AppUpdatesPresenter {
public void stopService() {
ServiceManager.on().stopService();
}
}
I have the test class like this
#RunWith(MockitoJUnitRunner.class)
public class AppUpdatesPresenterTest {
#Mock
AppUpdatesPresenter appUpdatesPresenter;
#Mock
ServiceManager serviceManager;
#Mock
Context context;
#Test
public void test_Stop_Service() throws Exception {
appUpdatesPresenter.stopService();
verify(serviceManager,times(1)).stopService();
}
}
When I tried to test that , if I call stopService() method , then ServiceManager.on().stopService(); called at least once .
But I am getting the following error
Wanted but not invoked:
serviceManager.stopService();
-> at io.example.myapp.ui.app_updates.AppUpdatesPresenterTest.test_Stop_Service(AppUpdatesPresenterTest.java:103)
Actually, there were zero interactions with this mock.
Not sure whats gone wrong .

When you call appUpdatesPresenter.stopService();, nothing happened as you didn't tell it what should be happened.
To make your test pass, you need stubbing the appUpdatesPresenter.
#Test
public void test_Stop_Service() throws Exception {
doAnswer { serviceManager.stopService(); }.when(appUpdatesPresenter).stopService()
appUpdatesPresenter.stopService();
verify(serviceManager).stopService();
}
Btw, the above test is meaningless as you stub all the things.
To make the test case meaningful, you should inject the ServiceManager instead of coupling it with AppUpdatePresenter.
public class AppUpdatesPresenter {
private final ServiceManager serviceManager;
public AppUpdatesPresenter(ServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
public void stopService() {
sm.stopService();
}
}
Then make the AppUpdatesPresenter under test.
#InjectMock AppUpdatesPresenter appUpdatesPresenter;
Now the test case doesn't rely on canned interaction but real implementation of your code.
#Test
public void test_Stop_Service() throws Exception {
appUpdatesPresenter.stopService();
verify(serviceManager).stopService();
}

Related

How to define only last test method assertion will be involved

I have a two class's for testing regression test. We have in some case more than one test method in the class and in the methods we are usually using assertions. I want to know if there any method is available, to make use #Rule test method only the last method in the class. Here is my code:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class JustOneClass extends ParentClass {
#Rule
public class GeneralRule articleHotspotRule = new class GeneralRule (this);
#Test
aMethod(){
Assert.assertTrue()
}
#Test
bMethod(){
Assert.assertTrue()
}
#Test
cMethod(){
Assert.assertTrue()
}
#Test
dMethod(){
if this assert is failed Assert.assertTrue()
}
}
We have a another class which extends TestWatcher
public class GeneralRule extends TestWatcher {
private ParentClass baseTest;
public GeneralRule (final GeneralRule generalRule) {
this.baseTest = generalRule;
}
#Override
protected void failed(final Throwable e, final Description description) {
baseTest.after();
}
}
in this case I want that baseTest.after() will be used only if assertion of dMedthod is failed.
Rather than using a rule to try and check for the failure, how about checking for the failure condition and then fail the test programatically? Certainly not as elegant or reusable as a rule but may satisfy your requirement.
#Test
public void dMethod() {
...
if(actual == false) { // check for failure scenario
after(); // call the after method
Assert.fail("hello failure"); // programatically fail the test
}
}

How do I use Mockito to mock a protected method?

I’m using Mockito 1.9.5. How do I mock what is coming back from a protected method? I have this protected method …
protected JSONObject myMethod(final String param1, final String param2)
{
…
}
However, when I attempt to do this in JUnit:
final MyService mymock = Mockito.mock(MyService.class, Mockito.CALLS_REAL_METHODS);
final String pararm1 = “param1”;
Mockito.doReturn(myData).when(mymock).myMethod(param1, param2);
On the last line, I get a compilation error “The method ‘myMethod’ is not visible.” How do I use Mockito to mock protected methods? I’m open to upgrading my version if that’s the answer.
This is not an issue with Mockito, but with plain old java. From where you are calling the method, you don't have visibility. That is why it is a compile-time issue instead of a run-time issue.
A couple options:
declare your test in the same package as the mocked class
change the visibilty of the method if you can
create a local (inner) class that extends the mocked class, then mock this local class. Since the class would be local, you would have visibility to the method.
Responding to the request for a code sample of option 3 from John B's answer:
public class MyClass {
protected String protectedMethod() {
return "Can't touch this";
}
public String publicMethod() {
return protectedMethod();
}
}
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
class MyClassMock extends MyClass {
#Override
public String protectedMethod() {
return "You can see me now!";
}
}
#Mock
MyClassMock myClass = mock(MyClassMock.class);
#Test
public void myClassPublicMethodTest() {
when(myClass.publicMethod()).thenCallRealMethod();
when(myClass.protectedMethod()).thenReturn("jk!");
}
}
You can use Spring's ReflectionTestUtils to use your class as it is and without needing of change it just for tests or wrap it in another class.
public class MyService {
protected JSONObject myProtectedMethod(final String param1, final String param2) {
return new JSONObject();
}
public JSONObject myPublicMethod(final String param1) {
return new JSONObject();
}
}
And then in Test
#RunWith(MockitoJUnitRunner.class)
public class MyServiceTest {
#Mock
private MyService myService;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(myService.myPublicMethod(anyString())).thenReturn(mock(JSONObject.class));
when(ReflectionTestUtils.invokeMethod(myService, "myProtectedMethod", anyString(), anyString())).thenReturn(mock(JSONObject.class));
}
}
Something like following worked for me, using doReturn() and Junit5's ReflectionSupport.
[Note: I tested on Mockito 3.12.4]
ReflectionSupport.invokeMethod(
mymock.getClass()
// .getSuperclass() // Uncomment this, if the protected method defined in the parent class.
.getDeclaredMethod("myMethod", String.class, String.class),
doReturn(myData).when(mymock),
param1,
param2);
John B is right, this is because the method you're trying to test is protected, it's not a problem with Mockito.
Another option on top of the ones he has listed would be to use reflection to gain access to the method. This will allow you to avoid changing the method you are testing, and avoid changing the pattern you use to write tests, and where you store these tests. I've had to do this myself for some tests where I was not allowed to change the existing code base which included a large number of private methods that needed to be unit tested.
These links explain Reflection and how to use it very well, so I will link to them rather than copy:
What is reflection and whit is it useful
How to test a class that has private methods, fields, or inner classes
WhiteBox.invokeMethod() can be handy.
public class Test extend TargetClass{
#Override
protected Object method(...) {
return [ValueYouWant];
}
}
In Spring, you can set it high high-priority like this:
#TestConfiguration
public class Config {
#Profile({"..."})
#Bean("...")
#Primary // <------ high-priority
public TargetClass TargetClass(){
return new TargetClass() {
#Override
protected WPayResponse validate(...) {
return null;
}
};
}
}
It is the same to override the origin bean.

How to have individual SetUp functions in Junit

I have two test functions and for each I want to have different #Before methods. How to achieve this ?
Although it seems to be convenient to organize all the test under the same class, for your case I think the best option is to separate the tests into different classes, each one with his corresponding setUp.
An alternative (I prefer the previous option) could be call the setUp directly in your test method, like the example as follows:
public class FooTest {
public void setUpMethod1() {
// do setUp things
}
public void setUpMethod2() {
// do setUp things
}
#Test
public void testMethod1() {
setUpMethod1();
// Test
}
#Test
public void testMethod2() {
setUpMethod2();
// Test
}
}
Only as a curiosity (IMO not recomended for your case), you can override the default junit RunListener with your own implementation. Method testStarted is executed before every test and you have access to class and methodName to be able to identify the running test. Dummy sample:
public class MyRunListener extends RunListener {
#Override
public void testStarted(Description description) throws Exception {
//...
Class testClass = description.getClass();
String methodName = description.getMethodName();
//...
}
}
Hope it helps.

how do I use powermockito verifyNew?

Having trouble with this. I've used Powermockito quite a bit in the past. Normally this is pretty smooth. I figured I'd post my problem rather than continue to rummage through examples. So the goal is to verify a call to new for a class. I don't think this is the most popular feature of powermockito.
Here's the test:
import static org.powermock.api.mockito.PowerMockito.verifyNew;
import static org.powermock.api.mockito.PowerMockito.whenNew;
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassUnderTest.class)
public class VerifyNewTest {
ClassUnderTest myClassUnderTest = new ClassUnderTest();
#Before
public void setUp() throws Exception {
}
#Test
public void test() throws Exception {
whenNew(Collaborator.class).withNoArguments().thenReturn(new Collaborator());
myClassUnderTest.doSomething();
verifyNew(Collaborator.class).withNoArguments();
}
}
and said classes
public class ClassUnderTest {
public void doSomething() {
new Collaborator();
}
}
public class Collaborator {
}
My goal was to make this as simple as possible. I suppose I could have added some mock objects and stubbed some behavior. Anyway, I get.
org.mockito.exceptions.misusing.UnfinishedStubbingException: Unfinished stubbing detected here:
-> at org.powermock.api.mockito.internal.invocationcontrol. MockitoNewInvocationControl.expectSubstitutionLogic(MockitoNewInvocationControl.java:65)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
Return a mock object in the whenNew() clause would work in your case.
#Test
public void test() throws Exception {
whenNew(Collaborator.class).withNoArguments().thenReturn(mock(Collaborator.class));
myClassUnderTest.doSomething();
verifyNew(Collaborator.class).withNoArguments();
}

How to run something after all the #Before's have happened?

We're using #Before's all along the hierarchy to get some test data inserted into the database before tests execute. I want to commit all that data to the database just before the #Test starts running.
One way to do this would be to commit the data as the last step in this test class' #Before method. But we have hundreds of such classes, and don't want to go in and modify all of those.
I've played with ExternalResource #Rule and TestWatcher #Rule...but they don't afford a way to hook in after all the #Before's have happened.
I'm thinking I need to look at building a custom TestRunner to do this.
Is that the right track?
What you are looking for, seems inconsistent to me. Settind some data and committing them are very close operations and shouldn't belong to different places. On the contrary, I would rather put them into one function and call it with actual parameters set to values you want to insert. Or use SQL strings as actual parameters. And call this finction from #Before
If you are insisting, there is no problem to do it. Create descendant classes for your Junit classes:
package ...;
import org.junit.Before;
public class NewAndBetterYourTest1 extends YourTest1 {
#Override
#Before
public void setUp() {
super.setUp(); // this is where you are setting everything.
makeCommits();
}
}
Only don't forget to launch these new tests
While you can't do quite what you are asking without a custom Runner, you could ensure that all of the data created in the #Before methods is committed with a Rule:
public class LocalDatabase extends ExternalResource {
private DataSource dataSource;
#Override
protected void before() {
dataSource = createLocalDatabase();
}
#Override
protected void after() {
try {
destoyLocalDatabase(dataSource);
} finally {
dataSource = null;
}
}
public void run(Callback callback) {
if (dataSource == null) {
throw new IllegalStateException("No DataSource");
}
Collection con = null;
try {
con = ds.getConnection(DB_USERNAME, PASSWORD);
callback.execute(con);
con.commit();
} finally {
if (con != null) con.close();
}
}
You can have this as a Rule in your base class:
public DatabaseTest {
#Rule
public LocalDatabase final localDatabase = new LocalDatabase();
}
And could could use it in a #Before method in any subclass
public UserDaoTest extends DatabaseTest {
#Before
public void populateInitialData() {
localDatabase.run(new Callback() {
#Override
public void execute(Connection con) {
...
}
});
}
...
}