10

consider my scenario

public class SomeClass {
  @Autowired @Qualifier("converter1") private IConverter converter1;
  @Autowired @Qualifier("converter2") private IConverter converter2;

  public void doSomeAction(String mimeType) {
    converter1.execute();
    converter2.execute();
  }
}

This is my code.

In order to test this

@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {
  @Mock(name="converter1") IConverter converter1;
  @Mock(name="converter2") IConverter converter2;
  @InjectMocks SomeClass class = new SomeClass();
  @Test
  public void testGetListOfExcelConverters() throws Exception {
    class.doSomeAction("abcd");
  }
}

Here the mocks are not getting injected, please help with the proper mechanism for mocking a qualified beans.

If this is not the right way to code using spring, please let me know the correct method for using this.

amith
  • 399
  • 1
  • 2
  • 11

5 Answers5

5

Not sure what error you are getting, but your test class doesn't compile because you have what looks like you intend to be a variable name using the keyword class. This worked for me:

@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {
    @Mock(name="converter1") IConverter converter1;
    @Mock(name="converter2") IConverter converter2;

    @InjectMocks
    SomeClass clazz = new SomeClass();

    @Test
    public void testGetListOfExcelConverters() throws Exception {
        clazz.doSomeAction("abcd");
        verify(converter1).execute();
        verify(converter2).execute();
    }
}

And by "worked for me" I mean that the test actually ran and passed. Note I added a couple of verify statements to assert that the injected mocks got called.

I used the SomeClass code you provided as-is.

jhericks
  • 5,833
  • 6
  • 40
  • 60
  • sorry about the typo about class, thanks for correcting it. I use springboot but some how my dependencies are not getting set and I get NPE while calling converter1.execute(). If possible can you throw some light on what could be the problem. – amith Jun 10 '16 at 10:12
  • You'll have to provide more details about your actual classes and/or configuration. As I said, the example you provided basically works (once you fix the typo) so I can't really guess what's wrong. – jhericks Jun 10 '16 at 14:08
5

For me, both existing answers were insufficient.

@riddy 's answer did not take into account different test cases.

@jhericks ' answer did not use the Spring context, which caused other issues down the line.

Here's my solution:

@MockBean
@Qualifier("myNamedBean")
private SomeBean someBean;

As simple as that.

Markus Appel
  • 3,138
  • 1
  • 17
  • 46
4

You can mock beans using a test configuration:

@Configuration
public class TestConfig {
   @Bean
   public MyService myService() {
      return Mockito.mock( MyService.class );
   }
}
riddy
  • 501
  • 1
  • 4
  • 17
  • and see https://tedvinke.wordpress.com/2014/02/13/mockito-why-you-should-not-use-injectmocks-annotation-to-autowire-fields/ on how to use InjectMocks and why you shouldnt ^^ – riddy Jun 07 '16 at 09:37
  • Thanks for the link its really helpful. I will remove injectmocks from my project. Second how do i specify the configuration class in test class, if possible can you provide some eg. – amith Jun 10 '16 at 10:11
  • easy, if the package name of the config class in your test folder matches the package name in the src folder it will be done automatically. – riddy Jun 13 '16 at 07:09
3

I've found this solution:

@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {

  @Mock()
  @Qualifier("converter1")
  IConverter converter1;

  @Mock() 
  @Qualifier("converter1")
  IConverter converter2;

  @InjectMocks SomeClassTest testObj = new SomeClassTest();

  @Test
  public void testGetListOfExcelConverters() throws Exception {
    testObj.doSomeAction("abcd");
    verify(converter1).execute();
    verify(converter2).execute();
  }
}

BTW, I haven't found this in doc.

turulb
  • 31
  • 1
2

In my app, the @Autowired beans are passed as constructor args. None of the variations (albeit JUnit 5 version) were working. Instead, I had to "kick it old school" and simply instantiate the mocks directly.

public class SomeClass {
  private final IConverter converter1;
  private final IConverter converter2;

  public SomemClass( @Autowired @Qualifier("converter1") conv1,
                     @Autowired @Qualifier("converter2") conv2 ) {
    this.converter1 = conv1;
    this.converter2 = conv2;
  }

  public void doSomeAction(String mimeType) {
    converter1.execute();
    converter2.execute();
  }
}

public class SomeClassTest {
  IConverter converter1;
  IConverter converter2;
  SomeClass pojo;

  @BeforeEach
  public void setup() {
    converter1 = Mockito.mock( IConverter.class );
    converter2 = Mockito.mock( IConverter.class );
    pojo = new SomeClass( converter1, converter2 );
  }

  @Test
  public void testGetListOfExcelConverters() throws Exception {
    pojo.doSomeAction("abcd");
  }
}
Charlie Reitzel
  • 809
  • 8
  • 13