I use spring boot 3
I try to do a test from the controller
userManager.findByUa
call a repository
Test
@ExtendWith(SpringExtension.class)
@WebMvcTest(value = UserController.class)
public class UserConnectionControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserManager userManager;
@Test
public void retrieveUserConnection() throws Exception{
UserConnection mockUserConnection = new UserConnection(158791, "Paul Smith", "1123977", "01");
mockUserConnection.setDisabled(false);
String expected = """
{
"userId": 158791,
"name": "Paul Smith",
"userAccess": "1123977",
"userType": "01",
"disabled": false
}
""";
Mockito.when(userManager.findByUa(Mockito.anyString())).thenReturn(mockUserConnection);
RequestBuilder requestBuilder = MockMvcRequestBuilders.get(
"/users/1123977").accept(
MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
JSONAssert.assertEquals(expected, result.getResponse()
.getContentAsString(), false);
}
}
When i run this test, i get this error
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaSharedEM_entityManagerFactory': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument
Main class
@SpringBootApplication(
scanBasePackages = { "com.acme.extranet", "com.acme.common" }
)
@EntityScan("com.acme.common")
@EnableJpaRepositories(basePackages = "com.acme.common")
public class ExtranetApplication {
public static void main(String[] args) {
SpringApplication.run(ExtranetApplication.class, args);
}
}
My entity and repository and in the common package who is a jar library use in the Extranet application
I don't know that your context and test strategy, so it is not an accurate hint. I think there are two options.
If you just want to use UserManager as test double, just make mock object by Mockito's static method. Remove dependencies of JPA for test.
package action.in.blog;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.Mockito.when;
@WebMvcTest(value = UserController.class)
public class TempTest {
@Autowired
private MockMvc mockMvc;
private UserManager userManager;
@Test
void test() {
userManager = Mockito.mock(UserManager.class);
when(userManager.findAll()).thenReturn(
List.of(new User(111))
);
List<User> result = userManager.findAll();
assertThat(mockMvc != null, equalTo(true));
assertThat(result.get(0).getId(), equalTo(111L));
}
}
@WebMvcTest annotation provide minimal context for MVC test. So that cannot use JPA functionalities. And You need to append two annotations.
package action.in.blog;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.Mockito.when;
@AutoConfigureMockMvc
@Transactional
@SpringBootTest
public class TempSecondTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserManager userManager;
@Test
void test() {
when(userManager.findAll()).thenReturn(
List.of(new User(111))
);
List<User> result = userManager.findAll();
assertThat(mockMvc != null, equalTo(true));
assertThat(result.get(0).getId(), equalTo(111L));
}
}