-1

Here is my test code

package com.tasks;

@ContextConfiguration(classes = ITest.class)
@ActiveProfiles(profiles = "test")
@RunWith(SpringJUnit4ClassRunner.class)
public class ITest {

  @Inject
  IAccessor iAccessor1;

  @Test
  public void testRun() {
  }

  @Configuration
  @Profile("test")
  @ComponentScan(basePackageClasses{com.tasks.ITest.class})
  public static class ITestConfiguration{

    @Bean
    @Primary
    public IAccessor iDataAccessor(){
        IAccessor iAccessor =  mock(IAccessor.class);
        return iAccessor;
    }
  }
}

I tried @Autowired instead of Inject, but got the same error.

In my class under test I have

@Component
public class ISync {

  @Inject
  private IAccessor iAccessor;


  public int someMethod(){

    iAccessor.someOtherMethod(); //want to mock out

  }
}

So I want to inject a mocked up value. However I get a depenedency error

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.database.iAccessor1' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}

It works generally for me, but I do not know what is the problem here in this particular case. I want the answer to what is the problem with my solution.

I already tried : Spring JUnit: How to Mock autowired component in autowired component 1) The accepted answer is using testContext.xml I do not use any xml. 2) I used @MockBean but I started getting other error.

java.lang.NoSuchMethodError: org.mockito.Mockito.mockingDetails(Ljava/lang/Object;)Lorg/mockito/MockingDetails;

TO rectify it I bumped the version of mockito-all 1.9.0 to 1.9.5 (though I don't know why is it trying to find it).

java.lang.NoSuchMethodError: org.mockito.internal.util.MockUtil.getMockSettings(Ljava/lang/Object;)Lorg/mockito/mock/MockCreationSettings;

I got it working by bumping the version to 1.0.19. But the value in the class under test was still null. So this didn't work for me.

I want to know what is the problem with my original solution?

Frank Neblung
  • 3,047
  • 17
  • 34
Bhavya Arora
  • 768
  • 3
  • 16
  • 35
  • Possible duplicate of [Spring JUnit: How to Mock autowired component in autowired component](https://stackoverflow.com/questions/19299513/spring-junit-how-to-mock-autowired-component-in-autowired-component) – tkruse Jan 06 '18 at 02:30
  • also just look at the 'Related' questions on the left, this is not a new question. – tkruse Jan 06 '18 at 02:31
  • Why do you want to inject a 'mocked' up value? Why not just use a mock via @Mock or mock(...)? – Sean Carroll Jan 06 '18 at 03:03
  • @tkruse I want to know the problem in my solution. Also the current solution required me to bump up the version. If I want to stay on the same version, I'll need my solution to work. – Bhavya Arora Jan 06 '18 at 03:04
  • @SeanCarroll Mock creates a mock but does not injects it to the autowired property which would be null upon calling the function of that class. – Bhavya Arora Jan 06 '18 at 03:06
  • Thats my point. Why do you need to autowire the property which is just the mock? Why not just use the mock directly? What is the benefit of the indirection of injecting the mock in what you have provided. – Sean Carroll Jan 06 '18 at 03:07
  • I do not send it as a parameter of the method call, how would the Mocked value reach the actual class? – Bhavya Arora Jan 06 '18 at 03:12
  • Sorry, solution does not work, as the mocked value does not reach the class under test and is null!! – Bhavya Arora Jan 06 '18 at 03:12
  • I dont think you've provided the details you are talking about. Your test method is empty and iAccessor1 isn't used in what you've provided – Sean Carroll Jan 06 '18 at 03:17
  • If you're attempting to use mock in the class you should also look at MockitoJUnitRunner – Sean Carroll Jan 06 '18 at 03:19
  • I think @RunWith(SpringJUnit4ClassRunner.class) I do not need MockitoJUnitRunner. – Bhavya Arora Jan 06 '18 at 03:22
  • Thats used for Spring's TestContext which per my understanding is different – Sean Carroll Jan 06 '18 at 03:23
  • It's giving me an error even with an empty method. It should have initialized the iAccessor because there is a static class providing the Bean. That should be enough. It's a working code(with the error). – Bhavya Arora Jan 06 '18 at 03:23
  • I have a Bean, so I will need to use it in my implementation. I am pretty sure about that. – Bhavya Arora Jan 06 '18 at 03:24
  • Yes but thats different than what my suggestion was. I'd be happy to talk more in chat – Sean Carroll Jan 06 '18 at 03:24
  • Sorry. We're talking about different things – Sean Carroll Jan 06 '18 at 03:25
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/162641/discussion-between-bhavya-arora-and-sean-carroll). – Bhavya Arora Jan 06 '18 at 03:26
  • In all the answers to all similar questions, do not just look at the 'accepted' answer, but look at all the answers, the highest voted one, and the newest one. – tkruse Jan 07 '18 at 02:34

2 Answers2

0

Make your class ISync to accept IAccessor in the constructor. Then in the test you will be able to pass a mock IAccessor to it and then verify that someOtherMethod() was called on your IAccessor mock.

Alexander Kulyakhtin
  • 47,782
  • 38
  • 107
  • 158
0

The function name for the

@Bean
@Primary
public IAccessor iDataAccessor(){
    IAccessor iAccessor =  mock(IAccessor.class);
    return iAccessor;
}

It started working as soon as I changed it to iAccessor1(). making it

public IAccessor iAccessor1()

Bhavya Arora
  • 768
  • 3
  • 16
  • 35