storm_buster
storm_buster

Reputation: 7568

How do you mock Environment interface?

I am trying to test my service which looks like :

import org.springframework.core.env.Environment;

@Service
public class MyService {
@Autowired Environment env;
...
...
}

How do I mock Environment Interface, or else how do I create one?

Upvotes: 20

Views: 51049

Answers (4)

Sam Brannen
Sam Brannen

Reputation: 31197

Spring provides mocks for property sources and the environment. Both of these can be found in the org.springframework.mock.env package of the spring-test module.

These are briefly documented in the reference manual in the Mock Objects section of the testing chapter.

Upvotes: 29

KarthikDev
KarthikDev

Reputation: 39

Implementation Class has @Autowired Environment env; So when you are running >JUnit test case you implementation class should have a constructor like below:

public class SampleImpl{
@Autowired
Environment env
public SampleImpl(Environment envObj){
this.env = envObj}
}

your Junit Test class should be as follows:

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.initMocks;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.springframework.core.env.Environment;
import static org.mockito.Mockito.when;
public class SampleTest {   

     @Mock Environment env;

     @Before
      public void init(){
          env = mock(Environment.class);     
          when(env.getProperty("file.location"))
            .thenReturn("C:\\file\\");        
      }

          @Test
          public void testCall()throws Exception{
              SampleImpl obj = new SampleImpl(env);
              obj.yourBusinessMethods();

          }
}

Hope this helps. Thanks Steve.

Upvotes: 3

Steve
Steve

Reputation: 9480

Using Mockito, you should be able to do it somewhat like the code below. Note that you need to either provide accessors so that you can set the Environment field at runtime. Alternatively, if you only have a couple of autowired fields, it can be cleaner to define a constructor where you can inject the Environment.

import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;

public class MyServicetest {

    // Define the Environment as a Mockito mock object
    @Mock Environment env;

    MyService myService;

    @Before
    public void init() {
        // Boilerplate for initialising mocks 
        initMocks();

        // Define how your mock object should behave
        when(this.env.getProperty("MyProp")).thenReturn("MyValue");

        // Initialise your service
        myService = new MyServiceImpl();

        // Ensure that your service uses your mock environment
        myService.setEnvironment(this.env);
    }

    @Test
    public void shouldDoSomething() {
        // your test
    }

}

Upvotes: 8

Ralph
Ralph

Reputation: 120781

In a Spring based test you can use: @ActiveProfiles so activate some Profile (but this is not a mock)

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("test.xml")
@ActiveProfiles("myProfile")
public class ProfileTest {

  @Autowired
  MyService myService

  @Test
  public void demo() {
      assertTrue(myService.env.acceptsProfiles("myProfile"));
  }
}

But I you need a mock then write your own or use a mocking framework (Mokito or JMock). Environment has an sublass AbstractEnvironment, where you just need to override customizePropertySources(MutablePropertySources propertySources) methode

@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
            Properties properties = ....
    propertySources.addLast(new MockPropertySource(properties));
}

Upvotes: 1

Related Questions