spring test without mocking - spring

I had to develop a Service in a non Spring project, starting to use Spring dependency injection (NOT SPRING BOOT). It's a test with real data so I don't want to mock any of the services used.
Let's say I have the following class:
#Service
public class Service1 {
private final Service2 service2;
public Service1(Service2 service2) {
this.service2 = service2;
}
public X doSomething() {
...
}
}
So in order to test Service1, I created a config class
#Configuration
public class SpringBeansConfig {
#Bean
public Service2 service1(Service2 service2) {
return new Service1(service2);
}
#Bean
public Service2 service2() {
return new Service2();
}
}
and the following test so Service2 is not mocked.
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = { Config.class })
public class Service1Test {
#Autowired
public Service1 sut;
#Test
public void myTest() {
X result = service1.soSomething();
}
}
But service1 is null. I'm sure I'm missing some configuration but error log is just telling me service1 is null.
Any help is appreciated.
Many thanks

Related

How to inject certain properties values during junit to a specific test

My Spring Boot app has some test that are reading their properties from the application.yml that is in the test folder.
cat:
maxAge:30
maxNameSize:10
all is working fine, but I like that in certain tests, other values will be injected:
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = {
Cat.class
})
#SpringBootTest
public class CatTest {
#Test
public void testX(){
//inject maxAge=90
// use maxNameSize from the application.yml
....
#Test
public void testZ(){
//inject maxNameSize=5
// use maxAge from the application.yml
....
}
Changing properties on method level is not supported by Spring at this moment.
You can use nested classes to accomplish this.
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = {
Cat.class
})
#SpringBootTest
public class CatTest {
#Nested
#SpringBootTest(properties = "cat.maxAge=90")
public class NestedTestX {
#Test
void testX() {
//noop
}
}
#Nested
#SpringBootTest(properties = "cat.maxNameSize=5")
public class NestedTestZ {
#Test
void testZ() {
//noop
}
}
}

Why did #TestConfiguration not create a bean for my test?

My service
#Service
public class StripeServiceImpl implements StripeService {
#Override
public int getCustomerId() {
return 2;
}
}
My test
public class StripeServiceTests {
#Autowired
StripeService stripeService;
#TestConfiguration
static class TestConfig {
#Bean
public StripeService employeeService() {
return new StripeServiceImpl();
}
}
#Test
public void findCustomerByEmail_customerExists_returnCustomer() {
assertThat(stripeService.getCustomerId()).isEqualTo(2);
}
}
The error: java.lang.NullPointerException. I had checked and the stripeService is actually null.
Since you are autowiring you need an applicationcontext so that Spring can manage the bean and then can get injected in your class. Therefore you are missing an annotation to create the applicationcontext for your testclass.
I have updated your code and it works now(with junit 5 on your classpath). In the case dat you are using junit 4 it should be #RunWith(SpringRunner.class) instead of #ExtendWith(SpringExtension.class):
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = TestConfiguration.class)
public class StripeServiceTests {
#Autowired
StripeService stripeService;
#TestConfiguration
static class TestConfig {
#Bean
public StripeService employeeService() {
return new StripeServiceImpl();
}
}
#Test
public void findCustomerByEmail_customerExists_returnCustomer() {
assertThat(stripeService.getCustomerId()).isEqualTo(2);
}
}

How to set and inject property Value from Test in Junit

My Service class uses a property set it application.properties
#Service
public class Service {
#Value("${my.prop}")
private String prop;
public Response doWork(String param1,String param2){
System.out.println(prop); //NULL!!!
}
}
I want to test it and set my own value:
Test Class:
#RunWith(MockitoJUnitRunner.class)
#TestPropertySource(locations = "application.properties",properties = { "my.prop=boo" })
public class ServiceUnitTest {
#InjectMocks
private Service service;
#Test
public void fooTest(){
Response re = service.doWork("boo", "foo");
}
}
But when I run the test, the value is null (not even the value that exists in application.properties).
I don't have experience with MockitoJUnitRunner, but I am able to achieve this using PowerMockRunner.
Set up the application context with a test configuration, and autowire the bean from you application context into your test class. You also shouldn't need the "locations = " bit in the #TestPropertySource annotation.
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(SpringRunner.class)
#TestPropertySource(properties = { "my.prop=boo" })
public class ServiceUnitTest {
#TestConfiguration
static class ServiceUnitTestConfig {
#Bean
public Service service() {
return new Service();
}
}
#Autowired
Service service;
#Test
public void fooTest(){
Response re = service.doWork("boo", "foo");
}
}

Cannot Mock an Injected Dependency in Controller Constructor

I am having a problem with mocking an object being injected in to a controller.
I am running an integration test. In my test I have the following setup:
#RunWith(SpringRunner.class)
#SpringBootTest
public class AuthenticationTests {
#TestConfiguration
public class Config {
#Bean
#Primary
public AbstractClient client() {
return new AbstractClient() {
#Override
public ManagedChannel getChannel() {
return new ManagedChannel();
}
};
}
}
}
In the controller being tested, AbstractClient is dependency injected like so:
#Controller
public class MyController {
private ManagedChannel managedChannel;
public MyController(AbstractClient client) {
managedChannel = client.getChannel();
}
}
Whenever I run the test, AbstractClient defined in the #TestConfiguration class is never injected - instead the default one is (which is annotated as #Service).
Can anyone help?

Null Pointer when using #SpringBootTest

I am using spring boot 1.4,
when using the #SpringBootTest annotation for integration test, it gives a null pointer.
#RunWith(SpringRunner.class);
#SpringBootTest
public class MyControllerTest {
#Test
public void mytest {
when().
get("/hello").
then().
body("hello");
}
}
and for main class:
#SpringApplication
#EnableCaching
#EnableAsync
public class HelloApp extends AsyncConfigureSupport {
public static void main(String[] args) {
SpringApplication.run(HelloApp.class, args);
}
#Override
public Executor getAsyncExecutor() {
...
}
}
Then in my controller:
#RestController
public class HelloController {
#Autowired
private HelloService helloService;
#RequestMapping("/hello");
public String hello() {
return helloService.sayHello();
}
}
HelloService
#Service
public class HelloService {
public String sayHello() {
return "hello";
}
}
But it ways says NullPointException when for helloService when processing request.
What am I missing?
You need to mock HelloService in your test class as your controller is calling a service .Here in your case Your Test class is not aware that there is any service available or not
The following example test class might help you. In this guide from spring an example is shown how to integration test a rest controller in a spring fashion way.
#RunWith(SpringRunner.class)
#SpringBootTest
#WebAppConfiguration
public class HelloControllerTest {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext webApplicationContext;
#Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
#Test
public void hello() throws Exception {
mockMvc.perform(get("/hello")).andExpect(content().string("hello"));
}
}

Resources