How to mock the mongoTemplate Object using Mockito FrameWork? - java

#RunWith(MockitoJUnitRunner.class)
public class EmailServiceTest {
// #InjectMocks
private EmailService emailService;
#Mock
private JavaMailSender javaMailSender;
#Mock
private MongoTemplate mongoTemplate;
#Mock
private FileStorageProperties fileStorageProperties;
#Mock
private Path fileStorageLocation;
}

Related

Mockito: injected component returns null

I have an issue. I use Mockito Framework to test a service but I have to inject another service into it in order to work. The problem is that I get a NullPonterException when I try to use the second service. Is there a special way to inject the different mock objects into the two services. My code currently looks like this:
#ExtendWith(MockitoExtension.class)
public class Service1Test {
#Mock
Repository1 repository1;
#Mock
Repository2 repository2;
#Mock
Repository3 repository3;
#Mock
Repository4 repository4;
#InjectMocks
Service1 service1;
#InjectMocks
Service2 service2;
}
#Service
public class Service1Impl implements Service1 {
private final Repository1 repository1;
private final Repository2 repository2;
#Autowired
public Service1Impl (Repository1 repository1, Repository2 repository2) {
this.repository1; = repository1;
this.repository2; = repository2;
}
}
#Service
public class Service2Impl implements Service2 {
private final Repository1 repository1;
private final Repository2 repository2;
private final Repository3 repository3;
private final Repository4 repository4;
#Autowired
public PostServiceImpl(PostRepository postRepository, CommentRepository commentRepository, TagRepository tagRepository, CategoryRepository categoryRepository) {
this.postRepository = postRepository;
this.commentRepository = commentRepository;
this.tagRepository = tagRepository;
this.categoryRepository = categoryRepository;
}
}

Mock Service class that has Autowired dependencies

I have a Service class & a config class as below:
public class MyService{
#Autowired
MyConfig myconfig;
#Autowired
private WebClient webClient;
private String result;
public String fetchResult(){
return webClient.get().uri(myConfig.getUrl()).retrieve().bodyToMono(String.class).block();
}
}
#ConfigurationProperties("prefix="somefield")
#Component
class MyConfig{
private String url;
//getter & setter
}
}
Below is the Junit:
#Runwith(MockitoJUnitRunner.class)
public class TestMe{
#InjectMocks
MyService myService;
#Test
public void myTest(){
when(myService.fetchResult().then return("dummy");
}
}
I am getting null pointer error when I run this class at webClient in Service class.
What could be the issue. I am new to JUnits.
How do I write a proper JUnit for this.
The easiest way to make the class testable is to use constructor injection
public class MyService{
private final MyConfig myconfig;
private final WebClient webClient;
private String result;
#AutoWired
MyService(
MyConfig myconfig,
WebClient webClient
) {
this.myconfig = myconfig;
this.webClient = webClient;
}
...
}

Unable to inject mock in Spring java bean?

I have a spring boot test as below
#SpringBootTest(class=AppConfig.class)
Public class AppTest{
#Autowired
private Product product
#Test
Public void test(){
.....
.....
}
}
My AppConfig.class is as below
Public clas AppConfig{
#Mock
EMailService emailService;
public AppConfig(){
MockitoAnnotations.initMocks(this)
}
#Bean
Public Product getProduct(){
return new Product();
}
}
Class Product{
#Autowired
private EMailService emailService
.....
......
}
Even after i defined #Mock EMailService emailService, whem i run the test, I get error EMailService bean not defined.
In your AppTest class
#SpringBootTest(class=AppConfig.class)
public class AppTest{
#Mock
private EMailService emailService;
#InjectMocks
private Product product;
#Test
public void test(){
.....
.....
}
}
Also, I think you do not need the definitions in the AppConfig class anymore

How can Mockito mocks be wired when there is no constructor?

I was going through this tutorial which sets up the SUT using a constructor but my question is what if there is no constructor e.g. if we have:
#Autowire private PetRepository petRepository;
#Autowire private VetRepository vetRepository;
#Autowire private OwnerRepository ownerRepository;
#Autowire private VisitRepository visitRepository;
in the service/controller. How we can set this up?
I prefer to annotate the setters instead of the attributes on the classes. For example:
public class SomeClass implements SomeInterface {
private PetRepository petRepository;
private VetRepository vetRepository;
private OwnerRepository ownerRepository;
private VisitRepository visitRepository;
... some methods ...
#Resource
public void setPetRepository(PetRepository petRepository) {
this.petRepository= petRepository;
}
#Resource
public void setVetRepository(VetRepository vetRepository) {
this.petRepository= vetRepository;
}
#Resource
public void setOwnerRepository(OwnerRepository ownerRepository) {
this.ownerRepository = ownerRepository;
}
#Resource
public void setVisitRepository(VisitRepository visitRepository) {
this.visitRepository= visitRepository;
}
}
Then you can create a test case like this with Mockito and Junit:
public class SomeClassTestCase {
#Mock
private PetRepository petRepository;
#Mock
private VetRepository vetRepository;
#Mock
private OwnerRepository ownerRepository;
#Mock
private VisitRepository visitRepository;
private SomeClass someClass;
#Before
public void before(){
MockitoAnnotations.initMocks(this);
someClass = new SomeClass();
someClass.setPetRepository(petRepository);
someClass.setVetRepository(vetRepository);
someClass.setOwnerRepository(ownerRepository);
someClass.setVisitRepository(visitRepository);
}
#Test
public void someTest() {
...
}
}
Hope it helps.
You can use Mockito's #InjectMocks annotation. This will instantiate and then inject the Mock dependencies, for example:
#RunWith(MockitoJUnitRunner.class)
public ServiceTest {
#Mock
PetRepository petRepository
// ...omitted mocks ...
#InjectMocks
ClinicServiceImpl service;
}
See the documentation for further usage examples and caveats.

#InjectMocks and non-mocked objects (Spring Data Repositories)

Is there any way to inject non-mocked objects with #InjectMocks?
My Setup has a UserSignupService with dependencies to a MailService and a UserRepository (a Spring Data Repository). I've a unit test creating a spy of the MailService and I annotated the UserSignupService with #InjectMocks. Sadly this won't inject the UserRepository (non-mocked) into the service class.
Combining #InjectMocks with #Autowired won't inject the mocked MailService, but the bean from the application context.
MockitoAnnotations.initMocks() is run in AbstractServiceTest.setUp(). This class also holds the configuration of the the unit test (SpringJunit4TestRunner, etc.)
public class UserSignupServiceTest extends AbstractServiceTest {
#Autowired #Spy
private MailService<UserActivationMail> mailService;
#InjectMocks
private UserSignupServiceImpl service;
#Before
public void setUp() throws Exception {
super.setUp();
}
}
#Service
public class UserSignupServiceImpl implements UserSignupService {
private final UserRepository repository;
private final MailService<UserActivationMail> mailService;
#Autowired
public UserSignupServiceImpl(UserRepository repository,
MailService<UserActivationMail> mailService) {
this.repository = repository;
this.mailService = mailService;
}
//methods...
}
You need to initialize your Mockito MockitoAnnotations.initMocks(this);
Here is sample Spring JUnit test class I have
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:config/spring-context.xml" })
public class SpringKPTest {
#Autowired
SomeClassA SomeClassA;
#Mock
SomeClassB SomeClassB;
#Before
public void init(){
MockitoAnnotations.initMocks(this);
}
}

Categories