Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock a service of a service in another service Junit

I have the following service :

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    protected ContractService contractService;

    private void saveInCache(MultipartFile multipartFile) {
        this.contractService.saveInCache(multipartFile);
    }
}

and another service

@Service
public class ClientServiceImpl implements ClientService {

    @Autowired
    protected ContractService contractService;

    private void getInfoOfFile(String multipartFileId) {
        DocumentInfo document = this.contractService.getInfo(multipartFileId);
        ///
    }
}

and I have my Junit

public class ClientControllerTest extends ApiWebTest {

  @Mock
  protected ContractService contractService;

  @Autowired
  @InjectMocks
  protected ClientService clientService = new ClientServiceImpl();

  @Before
  private void setup() {
     MockitoAnnotations.initMocks(this);
  }

  @Test
  private void testGetInfo() {
     // Code
     DocumentInfo multipartFile = new DocumentInfo();
     multipartFile.setMultipartFileId(1234);
     when(this.contractService.getInfo(multipartFile.getMultipartFileId())).thenReturn(multipartFile);

   // Test the Client service 'getInfoOfFile' method.
  }
}

When i run this test in debug mode, I see that the this.contractService.getInfo(multipartFileId); is returning me 'null'.

Where am I going wrong in mocking.

I have just mocked the ContractService in my JUnit. Do I need to mock even the AccountServiceImpl as well ?

EDIT : Adding the saveInCache and getInfo methods

private DocumentInfo getInfo(String documentId) {
        if (StringUtils.isEmpty(documentId)) {
            return null;
        }
        WriteLock lock = this.readWriteLock.writeLock();
        try {
            lock.lock();
            DocumentInfo cachedDocument = this.documentCache.get(documentId);
            return cachedDocument;
        } finally {
            if (lock != null) {
                lock.unlock();
            }
        }
    }

private DocumentInfo saveInCache(StreamingStorage document) {
        if (document == null) {
            throw new InvalidParameterException("Creative document is required to put into cache.");
        }
        WriteLock lock = this.readWriteLock.writeLock();
        try {
            lock.lock();
            DocumentInfo newCachedDocument = this.documentCache.put(document.getDocumentId(), document);
            return newCachedDocument;
        } finally {
            if (lock != null) {
                lock.unlock();
            }
        }
    }
like image 886
Vishnukk Avatar asked Sep 19 '17 06:09

Vishnukk


1 Answers

I think you're contradicting yourself with the declaration of the clientService.

You have:

@Autowired
@InjectMocks
protected ClientService clientService = new ClientServiceImpl();

This should create an autowired ClientService called clientService and inject the mocks. However the = new ClientServiceImpl() will then override the autowiring and create you a plain vanilla one (I think!). Also @Autowired and @InjectMocks are also not needed at the same time - you want to create a service with mocks injected - not an autowired object.

can you try changing you test like this:

@RunWith(MockitoJUnitRunner.class)
public class ClientControllerTest extends ApiWebTest {

  @Mock
  protected ContractService contractService;

  @InjectMocks
  protected ClientService clientService;

  @Test
  private void testGetInfo() {
     DocumentInfo multipartFile = new DocumentInfo();
     multipartFile.setMultipartFileId(1234);
     when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile);

  }
}

Adding @RunWith(MockitoJUnitRunner.class) means all the object creation happens without the need for any further work from you.

like image 68
robjwilkins Avatar answered Sep 30 '22 21:09

robjwilkins