2015-08-04 9 views
-1

Я хочу знать, что означает этот код?JUnit - вводить макет объекта, где фактическая реализация

mathApplication.setCalculatorService(calcService); 

Почему я должен использовать интерфейс и делать из него объект?

и что означает эта инъекция?

Вот мой тестер Код:

import org.easymock.EasyMock; 
import org.easymock.EasyMockRunner; 

import org.junit.Assert; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 

@RunWith(EasyMockRunner.class) 
public class MathApplicationTester { 

    private MathApplication mathApplication; 
    private CalculatorService calcService; 

    @Before 
    public void setUp() { 
     mathApplication = new MathApplication(); 
     calcService = EasyMock.createMock(CalculatorService.class); 
     mathApplication.setCalculatorService(calcService); 
    } 

    @Test 
    public void testAddAndSubtract() { 

     //add the behavior to add numbers 
     EasyMock.expect(calcService.add(20.0, 10.0)).andReturn(30.0); 

     //subtract the behavior to subtract numbers 
     EasyMock.expect(calcService.subtract(20.0, 10.0)).andReturn(10.0); 

     //activate the mock 
     EasyMock.replay(calcService); 

     //test the subtract functionality 
     Assert.assertEquals(mathApplication.subtract(20.0, 10.0), 10.0, 0); 

     //test the add functionality 
     Assert.assertEquals(mathApplication.add(20.0, 10.0), 30.0, 0); 

     //verify call to calcService is made or not 
     EasyMock.verify(calcService); 
    } 
} 
+0

Он называется Injection Dependency & описывается в http://stackoverflow.com/questions/130794/what-is-dependency-injection –

+0

Угадайте его подсказку для RTFM ... – dngfng

ответ

0

MathApplication является зависит на CalculatorService, которая обеспечивает - как предполагает его название - сервис для расчетов.

Однако в модульных тестах, вы хотите проверить только класс тестируемых (MathApplication), так что вы хотите заменить все зависимости от вашей собственной реализации, над которым вы имеете полный контроль. Для этого вы используете макет.

calcService = EasyMock.createMock(CalculatorService.class); 

Dependency инъекция является шаблоном, который «впрыскивает» объект, который вы зависимы от в основной объект.

Существует три подхода к получению экземпляров объектов, от которых зависит класс.

public class MathApplication { 
    // I need an instance of CalculatorService inside the code of MathApplication 
    ... 
} 

1: Создание объекта внутри кода MathApplication (не имеет значения, если calculatorService является локальным или атрибут класса). Это не очень рекомендуемый способ.

public double subtract(double a, double b) { 
    CalculatorService calculatorService = new SomeFastCalculatorService(); 
    return calculatorService.subtract(a, b); 
} 

2: Делегировать задачу конкретизации внешнего провайдера, называется завода:

public double subtract(double a, double b) { 
    CalculatorService calculatorService = CalculatorServiceFactory.getInstance(); 
    return calculatorService.subtract(a, b); 
} 

3: Пусть кто-то из-за пределы впрыскивать экземпляр через точку инъекции, либо с помощью конструктора с помощью метода сеттера.

Используется в основном для создания «дерева зависимостей» для всего приложения (обычно с использованием фреймов, таких как Spring Dependency Injection или JavaEE CDI). Здесь используется, чтобы ввести свой фиктивный объект в класс под тест:

mathApplication.setCalculatorService(calcService); 

Позже, в методе @Test, вы точно настроить поведение вашего фиктивного объекта.

EasyMock.expect(calcService.add(20.0, 10.0)).andReturn(30.0); 

следует читать как "когда calcService.add() вызывается с 20 и 10, дают 30".

И в конце концов вы:

  1. Test, если ваш испытанный метод возвращает то, что, как ожидается, - assertXXX()
  2. испытания, если calcService был использован - verify()

Btw, код

Assert.assertEquals(mathApplication.subtract(20.0, 10.0), 10.0, 0); 

содержит ошибки - просмотрите т он documentation. Правильно должно быть

Assert.assertEquals(10.0, mathApplication.subtract(20.0, 10.0), 0); 

Он работает почти так же, только вы получите более соответствующее сообщение об ошибке, если тест не работает:

Assertion error - expected 10.0, but was 11.0. 

И в любом случае, было бы лучше читаемым, если написано как:

double expected = 30.0; 
double actual = mathApplication.subtract(20.0, 10.0); 
Assert.assertEquals(expected, actual, 0.0000000001); // never expect exact floating point result 

и почему вы должны интерфейс: это хорошая практика :) это проще для рамочных издеваться интерфейсом, чем класс (и некоторые фиктивные структуры даже не может макет класса). И это заставляет вас научиться отделять интерфейс от его реализации и писать лучшие тестируемые классы.

+0

действительно полезный человек. Я знаю, что такое код. я просто не могу изобразить часть инъекции: \. почему мы это делаем? – Hamid

+0

Итак, теперь вы поняли? :) Кстати, прочитайте также о правильном использовании assert(). –

+0

Я читал о утверждении другого материала в моем коде. но инъекция, noo :( вы можете мне помочь? – Hamid