admin管理员组文章数量:1124660
In the setup in my test, the line:
when(kc.getToken()).thenReturn(token);
does not work and I get the following error from the ServiceImplementation
:
java.lang.NullPointerException: Cannot invoke "services.KeycloakService.getToken()" because "this.kc" is null
I am using the following dependencies:
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.mockito:mockito-core:5.14.2'
testImplementation 'org.mockito:mockito-junit-jupiter:5.14.2'
WHAT I TRIED:
- run the
testMockInjection
: all tests are green. - run the
testUpdate
: I see that the code from the Service implementation stops in the line
String zaToken = kc.getToken
and gives the aforementioned error
- the message in the set up is printed as expected
- I tried using a spy instead of a mock but it did not work again. Also, as I understand, It is better to use the mock because I want to 'fake' the whole service and need to stub just one function.
- Test import is the correct one
- I am using
@ExtendWith(MockitoExtension.class)
,@BeforeEach
and@InjectMocks
which work in my other tests.
However, I also tried MockitoAnnotations.initMocks(this)
and the error remained.
SERVICE IMPLEMENTATION CODE
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
...
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
...
import services.AasService;
import services.KeycloakService;
@Service
public class AasServiceImpl implements AasService{
private final RestTemplate restTemplate;
@Autowired
private KeycloakService kc;
@Value("${ass.server}")
private String aasUri;
@Value("${ass.id}")
private String aasIdShort;
public AasServiceImpl (RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public void update(String applicationUri, String nodeId, JSONObject value) {
System.out.println(applicationUri);
System.out.println(nodeId);
System.out.println(value);
String submodelElementValueId = applicationUri.replace(":", "_") + nodeId.replace("i=", "");
System.out.println(submodelElementValueId);
if (kc instanceof KeycloakServiceImpl) {
System.out.println("This is original service.");
} else {
System.out.println("This is not the original service.");
//this is the option printed
}
//problematic line is the following
String zaToken = kc.getToken();
//this is not printed in the code
System.out.println(zaToken);
try {
updateValue("DefectDetectionSkill", "Inputs", submodelElementValueId, value, zaToken);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
TEST CODE:
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
...
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
...
import org.junit.jupiter.api.BeforeEach;
import services.KeycloakService; //this is an interface
@ExtendWith(MockitoExtension.class)
public class AasServiceImplTest {
@Mock
private KeycloakService kc;
@Mock
private RestTemplate restTemplate;
@InjectMocks
private AasServiceImpl aasService;
@BeforeEach
void setUp() {
String token = "mockToken";
when(kc.getToken()).thenReturn(token);
ResponseEntity<String> response= new ResponseEntity<>("", HttpStatus.OK);
when(restTemplate.exchange(anyString(), any(), any(), eq(String.class))).thenReturn(response);
System.out.println("set up runs");
//this message is printed
}
/*
@Test
void testMockInjection() {
assertNotNull(kc, "KeycloakService mock is not injected!");
assertNotNull(restTemplate, "RestTemplate mock is not injected!");
assertNotNull(aasService, "AasServiceImpl is not initialized!");
}
*/
@Test
void testUpdate() {
//Arrange
String applicationUri = "http://mock_uri";
String nodeId="i=ioanna";
JSONObject value = new JSONObject();
value.put("Value", 1234);
//Act
aasService.update(applicationUri, nodeId , value);
System.out.println("Value: " + value.get("Value"));
//Assert
assertNotNull(kc, "KeycloakService mock is not injected!");
//verify(kc, times(1)).getToken();
//verify(restTemplate, atLeastOnce()).exchange(anyString(), any(), any(), eq(String.class));
}
In the setup in my test, the line:
when(kc.getToken()).thenReturn(token);
does not work and I get the following error from the ServiceImplementation
:
java.lang.NullPointerException: Cannot invoke "services.KeycloakService.getToken()" because "this.kc" is null
I am using the following dependencies:
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.mockito:mockito-core:5.14.2'
testImplementation 'org.mockito:mockito-junit-jupiter:5.14.2'
WHAT I TRIED:
- run the
testMockInjection
: all tests are green. - run the
testUpdate
: I see that the code from the Service implementation stops in the line
String zaToken = kc.getToken
and gives the aforementioned error
- the message in the set up is printed as expected
- I tried using a spy instead of a mock but it did not work again. Also, as I understand, It is better to use the mock because I want to 'fake' the whole service and need to stub just one function.
- Test import is the correct one
- I am using
@ExtendWith(MockitoExtension.class)
,@BeforeEach
and@InjectMocks
which work in my other tests.
However, I also tried MockitoAnnotations.initMocks(this)
and the error remained.
SERVICE IMPLEMENTATION CODE
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
...
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
...
import services.AasService;
import services.KeycloakService;
@Service
public class AasServiceImpl implements AasService{
private final RestTemplate restTemplate;
@Autowired
private KeycloakService kc;
@Value("${ass.server}")
private String aasUri;
@Value("${ass.id}")
private String aasIdShort;
public AasServiceImpl (RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public void update(String applicationUri, String nodeId, JSONObject value) {
System.out.println(applicationUri);
System.out.println(nodeId);
System.out.println(value);
String submodelElementValueId = applicationUri.replace(":", "_") + nodeId.replace("i=", "");
System.out.println(submodelElementValueId);
if (kc instanceof KeycloakServiceImpl) {
System.out.println("This is original service.");
} else {
System.out.println("This is not the original service.");
//this is the option printed
}
//problematic line is the following
String zaToken = kc.getToken();
//this is not printed in the code
System.out.println(zaToken);
try {
updateValue("DefectDetectionSkill", "Inputs", submodelElementValueId, value, zaToken);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
TEST CODE:
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
...
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
...
import org.junit.jupiter.api.BeforeEach;
import services.KeycloakService; //this is an interface
@ExtendWith(MockitoExtension.class)
public class AasServiceImplTest {
@Mock
private KeycloakService kc;
@Mock
private RestTemplate restTemplate;
@InjectMocks
private AasServiceImpl aasService;
@BeforeEach
void setUp() {
String token = "mockToken";
when(kc.getToken()).thenReturn(token);
ResponseEntity<String> response= new ResponseEntity<>("", HttpStatus.OK);
when(restTemplate.exchange(anyString(), any(), any(), eq(String.class))).thenReturn(response);
System.out.println("set up runs");
//this message is printed
}
/*
@Test
void testMockInjection() {
assertNotNull(kc, "KeycloakService mock is not injected!");
assertNotNull(restTemplate, "RestTemplate mock is not injected!");
assertNotNull(aasService, "AasServiceImpl is not initialized!");
}
*/
@Test
void testUpdate() {
//Arrange
String applicationUri = "http://mock_uri";
String nodeId="i=ioanna";
JSONObject value = new JSONObject();
value.put("Value", 1234);
//Act
aasService.update(applicationUri, nodeId , value);
System.out.println("Value: " + value.get("Value"));
//Assert
assertNotNull(kc, "KeycloakService mock is not injected!");
//verify(kc, times(1)).getToken();
//verify(restTemplate, atLeastOnce()).exchange(anyString(), any(), any(), eq(String.class));
}
Share
Improve this question
edited yesterday
Mureinik
310k54 gold badges346 silver badges385 bronze badges
asked 2 days ago
joanjoan
211 silver badge1 bronze badge
New contributor
joan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
4
|
1 Answer
Reset to default 1It seems like @InjectMock
is failing to mix field injection and constructor argument injection. Either have both the restTemplate
and kc
fields autowired:
@Service
public class AasServiceImpl implements AasService {
// No explicit constructor!
@Autowired
private RestTemplate restTemplate;
@Autowired
private KeycloakService kc;
...
Or have them both as constructor arguments:
@Service
public class AasServiceImpl implements AasService {
private RestTemplate restTemplate;
private KeycloakService kc;
public AasServiceImpl (RestTemplate restTemplate, KeycloakService kc) {
this.restTemplate = restTemplate;
this.kc = kc;
}
...
本文标签: junit testing error in java (eclipse) set up quotwhenquot does not workStack Overflow
版权声明:本文标题:junit testing error in java (eclipse)- set up "when..." does not work - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736643016a1946040.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
@InjectMocks
sees that there is a mock to be injected via constructor, and then it injects only that, instead of also injectingkc
via field injection. Does@InjectMocks
use all injection types, or just the first one it finds (i.e. it can do constructor injection and therefore only does that)? – k314159 Commented 2 days ago