2013-03-26 4 views
7

Я использую весну в своем приложении, и я хочу написать модульные тесты для всех моих классов. Я вызываю несколько внешних веб-сервисов из своего приложения, и я хочу издеваться над ими, используя Mockito, так как я просто хочу проверить свою функциональность.Использование аннотаций Mockito с весной

Допустим, у меня есть следующий сценарий

Это мой интерфейс вебсервис

public interface MyWebService { 
    public String getSomeData(int id); 
} 

Я использую вышеуказанное обслуживание таким образом

public interface MyService { 
    int doSomethingElse(String str); 
} 

public class MyServiceImpl implements MyService { 

    private MyWebService myWebService; 

    int doSomethingElse(String str) { 
     ..... 
     myWebService.getSomeData(id); 
     ... 
    } 
} 

public interface MyService1 { 
    Stirng methodToBeTested(); 
} 


public class Class1 implements MyService1{ 
    @Resource 
    private MyService myService; 

    public Stirng methodToBeTested() { 
     myService.doSomethingElse(".."); 
    } 
} 

Я написал тестовый UINT случай, как показано ниже. Я шпионил MyService здесь, чтобы запустить модульный тест.

public class class1Test { 

    @Spy 
    MyService myService; 

    @Resource 
    @InjectMocks 
    Class1 class1; 

    public void setUPTest() { 
     MockitoAnnotations.initMocks(this); 
    Mockito.doReturn(123).when(myService).doSomethingElse("someString"); 
    } 

    @Test 
    public void methodToBeTestedTest() { 
     this.setUPTest(); 
      ... 
      class1.methodToBeTested(); 
    } 

} 

Когда я запускаю тест, что я вижу в том, что я получаю значение из вебсервиса InstEd, что я уже в то время как гася.

Может ли кто-нибудь помочь мне с этим? (. И полезно, например, утверждать наличие или отсутствие метода транзитивных вызовов)

+0

Смотрите также http://stackoverflow.com/questions/2457239/injecting-mockito-mocks-into-a-spring-bean – Vadzim

ответ

5

Я решил эту проблему с помощью Spring Java конф. Я расширил свой конфигурационный файл по умолчанию в своем тестовом конфигурационном файле.

@Configuration 
    public class TestConfig extends DefaultConfig { 

     @Bean 
     public MyService myService() { 
     return Mockito.spy(new MyServiceImpl()); 
     } 
    } 

Теперь мой тестовый класс идет как этот

public class class1Test { 

    @Resource 
    MyService myService; 

    @Resource 
    Class1 class1; 

    public void setUPTest() { 
     MockitoAnnotations.initMocks(this); 
    Mockito.doReturn(123).when(myService).doSomethingElse("someString"); 
    } 

    @Test 
    public void methodToBeTestedTest() { 
     this.setUPTest(); 
      ... 
      class1.methodToBeTested(); 
    } 

} 
3

@Spy используются, чтобы шпионить за то, что происходит при вызове службы, что вы хотите, это @Mock аннотаций:

public class class1Test { 
    @Mock MyService myService; 
    ... 

Это будет приводят ко всем myService методам, возвращающим нуль, запрещайте их переопределять с помощью doReturn/when.

Кстати, вместо того, чтобы вызывать setUpTest() из ваших методов тестирования, вы должны аннотировать его @Before.

Приветствия,

+0

У меня есть здесь используется другой метод, потому что в MyService есть другие методы, которые необходимо отключить доцент (это просто пример кода, который похож на мой). – rahul

1

Это должно подходит ваша потребность:

@RunWith(MockitoJunitRunner.class) 
public class class1Test { 

    @Mock 
    private MyService myService; 

    private Class1 class1; 

    @Before 
    public void setUp() { 
     this.class1 = new Class1(myService); // creates this constructor. 
    } 

    @Test 
    public void methodToBeTestedTest() { 
     this.class1.methodToBeTested(); 
     Mockito.verify(this.myService).doSomethingElse(/* put expected arg here */); 
    } 
} 

Смотрите также official doc.

2

Вы имеете в виду anyString(), а не «someString» в вашем методе setUp? Это также может быть eq("someString"), если вы вызываете свой метод с определенной строкой.

Из моего понимания Mockito я не использую spys, так как они, вероятно, указывают на проблему дизайна класса. Почему бы вам не @Mock весь MyService, так;

@Mock MyService myService; 


public void setUpTest() { 
    MockitoAnnotations.initMocks(this); 
    when(myService.doSomethingElse(anyString)).thenReturn(123); 
} 
+0

@coder У меня был подобный класс, пока я не пришел, чтобы проверить его, когда понял, что мой класс делая слишком много вещей, затрудняя модульный тест. Рассмотрите разделение работы веб-сервиса на класс обработчика. Таким образом, вы можете построить свой класс с помощью обработчика mock'ed и покончить с '' '' @ Spy''''. Любые обращения к ws могут быть просто издевались над традиционными инструментами, не связанными с шпионажем. – OceanLife

+0

Это решит проблему, но печально то, что я не могу изменить первоначальную реализацию MyService или MyServiceImpl. – rahul

+0

Ах, да, вы правы, чтобы использовать шпиона. Я не понимал. Они особенно полезны при работе с сторонним/устаревшим кодом. Мой совет о Матчи дает лучшие издевательские результаты? – OceanLife

1

Modified,

public class class1Test { 

    @Mock 
    private MyService myService; 

    private Class1 class1; 

    @Before 
    public void onceBeforeEachTest() { 
     MockitoAnnotations.initMocks(this); 
     this.class1 = new Class1(myService); 
     Mockito.when(myService).doSomethingElse(anyString()).thenReturn(123); 
    } 

    @Test 
    public void methodToBeTestedTest() { 
      class1.methodToBeTested(); 
    } 
} 
+0

У меня нет конструктора, который принимает объект в качестве параметра. – rahul

3

Чтобы заменить Bean с издеваться в некотором тестовом использовании Springockito или лучше Springockito-annotations.

Что-то, как это должно работать:

@ContextConfiguration(loader = SpringockitoContextLoader.class, 
    locations = "classpath:/context.xml") 
public class SpringockitoAnnotationsMocksIntegrationTest extends AbstractJUnit4SpringContextTests { 

    @WrapWithSpy 
    private MyService innerBean; 

    @Resource 
    Class1 class1; 

    public void setUPTest() {   
     Mockito.doReturn(123).when(myService).doSomethingElse("someString"); 
    } 

    @Test 
    public void methodToBeTestedTest() { 
    this.setUPTest(); 
     ... 
     class1.methodToBeTested(); 
    } 

}

+0

Я видел вышеупомянутую ссылку. Как добавить шпиона «myService» в «class1» с помощью springockito. В Class1 «MyService» является частным и не имеет сеттера. – rahul

+0

@coder, обновлено. Если в вашем реальном контексте myService вводится в Class1, ему также будет добавлен WrapWithSpy. –

+0

Я использую конфигурацию весны java для инициализации боба, поддержка дождевальщика springockito. – rahul