I have a POJO class:
#Data #Document
public class RoomPreferences{
private TypeEnum roomType;
private BigDecimal minLen;
private BigDecimal maxLen;
private List<BigDecimal> defaultPrices;
}
I want to populate a RoomPreferences object at test and I am using Mockito, but my RoomPreferences object's fields are always null.
public class TestingClass {
#Mock private RoomPreferences roomPreferences;
#InjectMocks public RoomServiceImpl roomService;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
when(roomPreferences.getMinLen()).thenReturn(BigDecimal.valueOf(10));
...
}
}
What I read out of this testing class:
public class TestingClass {
#Mock private RoomPreferences roomPreferences;
#InjectMocks public RoomServiceImpl roomService;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
when(roomPreferences.getMinLen()).thenReturn(BigDecimal.valueOf(10));
...
}
}
is that roomService of type RoomServiceImpl has an attribute of type RoomPreferences. And this attribute will be injected with the mocked object "roomPreferences".
The mocked object won't be populated with any value of the real class.
What you do is define what the mock should do when a method (as in the real class) is called on it:
when(roomPreferences.getMinLen()).thenReturn(BigDecimal.valueOf(10));
If you wan to assing a value to a property then don't mock the class and use the real class instead.
I am guessing that the problem you are facing is setting the RoomPreferences attribute in the roomService object. If that is the case you should add that class to the question.
Related
I have a java class that I am setting up to store LoL champions in a project also using lombok (thus the lack of getters and setters) and Spring. The class looks like this:
#Data
#NoArgsConstructor
#AllArgsConstructor
public class Champion {
#Id
private String champName;
private String role;
private List<String> type; // <--- how do I populate this?
private String phrase;
private List<Champion> counterTo; //<--- or this?
private List<Champion> counteredBy;// <-- you get the idea.
}
I'm overriding the run() method from spring using commandLineRunner in my main application class but I don't know how to populate the lists when I invoke the constructor using Spring's .save() method when persisting into my MongoDB. Can anyone help?
Here is the main class below for context:
public class PlaygroundApplication implements CommandLineRunner {
#Autowired ChampionRepository repo;
public static void main(String[] args) {
SpringApplication.run(PlaygroundApplication.class, args);
}
#Override
public void run(String...args){
repo.deleteAll();
//repo.save("CHAMPION_ENTITY_GOES_HERE);
}
}
If I understand you correctly, you can try new a object and set the param it or Custom constructor
Java thinks my mocked Course class object is null at the line when().thenReturn().
class StudentTest {
#Mock
Course courseMock1;
#Test
void student_getTeacherNames_should_return_list_of_full_names() {
when(courseMock1.getEAP()).thenReturn(1);
}
public class Course {
public Course(String courseName, String name, LocalDate startDate, LocalDate endDate, Integer EAP, Teacher teacher) {
this.courseName = courseName;
this.name = name;
this.startDate = startDate;
this.endDate = endDate;
this.EAP = EAP;
this.teacher = teacher;
}
public Integer getEAP() {
return EAP;
}
}
I have tried:
#RunWith(MockitoJUnitRunner.class)
class StudentTest{...
--
#Before
public void setup(){
MockitoAnnotations.initMocks(this);
}
--
#Rule public Mocks mocks = new Mocks(this);
none of which solve NPE.
Also tried (using mocked Teacher object as one of the parameters)
#Mock
Course courseMock1 = new Course(params..);
which yielded:
MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'
Annotate StudentTest class with #RunWith(MockitoJUnitRunner.class).
Declare StudentTest class as public.
Declare student_getTeacherNames_should_return_list_of_full_names method as public.
Run the test class.
#RunWith(MockitoJUnitRunner.class)
public class StudentTest {
#Mock
Course courseMock1;
#Test
public void student_getTeacherNames_should_return_list_of_full_names() {
Mockito.when(courseMock1.getEAP()).thenReturn(1);
assertThat(courseMock1.getEAP()).isEqualTo(1);
}
}
What test framework are you using ? junit 4 or junit 5 ?
If junit5 , then the test class should be annotated with #ExtendWith(MockitoExtension.class)
An alternative could be to rely purely on code (not using annotation).
The code would become
class StudentTest {
Course courseMock1 = Mockito.mock(Course.class);
...
}
To use #Mock annotations you need to import org.mockito.MockitoAnnotations; and call MockitoAnnotations.initMocks. Note that the method has to be called before each test.
#BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
}
I used mistakenly #Before instead of #BeforeEach
Having the following classes :
public class A {
#Autowired
private Set<IClient> clients;
}
public class B implements IClient { }
public class C implements IClient { }
#RunWith(MockitoJUnitRunner.class)
public class Atest {
#InjectMocks
A a;
#Mock
IClient clients;
}
How I can use mocks for the Set of interfaces that will include both class B and C?
Use constructor injection insted of field injection, then create two mocks, put them in a set, and call your constructor with that set. For example:
public class Atest {
private A a;
#Mock
private IClient mockAClient;
#Mock
private IClient mockBClient;
#Before
public void prepare() {
a = new A(new HashSet<>(Arrays.asList(mockAClient, mockBClient));
}
}
How to mock super method call from mocked method
public class A extends B{
#Override
public retrieveData(){
//some action here
super.retrieveData();
}
}
abstract class B extends C{
//init super fields here
}
public class C{
public String retrieveData(){
//some return
}
}
Public Atest{
#InjectMock
A a;
#Mock
C parent; //also tryed for B but the same effect
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testDetailsRetrievePageList(){
when(parent.retrieveData()).thenReturn("stub");
String s = a.retrieveListData();
Assert.assertEquals("stub", s);
}
}
Didn't help Mockito How to mock only the call of a method of the superclass and post like that.
everytime my super is null in A class
I'm planning to create my objects in my Spring MVC using the below setup but How can I inject values to my MyService ie; instantiate the object with default value...
public class MyController {
private MyService myService;
#Autowired
public void setMyService(MyService aService) { // autowired by Spring
this.myService = aService;
}
#RequestMapping("/blah")
public String someAction()
{
// do something here
myService.foo();
return "someView";
}
}
MyService
class Myservice(){
String servicename;
public Myservice(servicename){
this.servicename = servicename;
}
}
Without Spring
MyService first = new MyService("firstservice");
MyService second = new MyService("secondservice");
Just declare your constructor with #Autowired to mark it as the constructor to use and its parameter with #Value to indicate the value to use.
#Autowired
public Myservice(#Value("example") String servicename){
Or use a placeholder
#Autowired
public Myservice(#Value("${placeholder.key}") String servicename){
Firstly, your exam are wrong on using Spring DI. To inject Myservice type to another You should declare MyService as a interface instead:
interface Myservice(){
public void foo();
}
After that, declare an implementation of this interface (again, use Spring DI to inject String type):
class BarService() implements Myservice{
String servicename;
#Autowired
public Myservice(#Value("servicename") String servicename){
this.servicename = servicename;
}
public void foo(){
}
}