我想知道这段代码的含义:
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 :(得分:0)
MathApplication
上的CalculatorService
是依赖,它提供 - 正如其名称所示 - 为计算提供服务。
但是,在单元测试中,您只想测试受测试的类(MathApplication
),因此您希望替换所有依赖项 strong>您自己的实施,您可以完全控制。为此,您可以使用模拟。
calcService = EasyMock.createMock(CalculatorService.class);
依赖注入是一种将您依赖的对象“注入”主对象的模式。
获取类所依赖的对象实例有三种方法。
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:将实例化任务委托给外部提供者,名为 factory :
public double subtract(double a, double b) {
CalculatorService calculatorService = CalculatorServiceFactory.getInstance();
return calculatorService.subtract(a, b);
}
3:让来自外部的人通过提供注入点来注入实例,或者通过setter方法的构造函数。
它通常用于构建整个应用程序的“依赖关系树”(通常使用Spring Dependency Injection或JavaEE CDI等框架)。这里它用于将模拟对象注入到测试类中:
mathApplication.setCalculatorService(calcService);
稍后,在您的@Test
方法中,您确切地设置了模拟对象的行为。
EasyMock.expect(calcService.add(20.0, 10.0)).andReturn(30.0);
被读作“当用20和10调用calcService.add()
时,给出30”。
最后你:
assertXXX()
verify()
顺便说一下,代码
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
为什么你应该接口:这是一个很好的做法:)框架模拟一个接口比一个类(和一些模拟框架甚至不能模拟一个类)更容易。它引导您学习将接口与其实现分离并编写更好的可测试类。