您好我已经实现了一系列使用dagger 2 Injection为每个类注入依赖项的类,我试图模拟它们来运行我的单元测试但是它无法初始化从较低层类中找到的依赖项有依赖。
这在真实的环境中工作正常,但不适用于测试
我尝试将所有依赖项标记为Spy或Mock,但它似乎只是在我调用的类的第一层上注入模拟。下面是三个标记为ExampleOne,Two,Three的类,其次是测试类。
ExampleOne有一个方法可以调用ExampleTwo中的另一个方法,然后最后从ExampleThree调用另一个方法。
只有ExampleTwo才能使mock / spy注入正常而不是ExampleThree。
public class ExampleOne{
@Inject
ExampleTwo exampleTwo;
//implementations below
public void doSomethingOne(){
exampleTwo.doSomethingTwo;
}
}
public class ExampleTwo{
@Inject
ExampleThree exampleThree
public void doSomethingTwo(){
exampleThree.doPrintHello();
}
}
public class ExampleThree{
public void doPrintHello(){
Log.d("Print","Hello")
}
}
以下是我的测试
@RunWith(MockitoJUnitRunner.class)
public class TestExamples(){
@InjectMocks
ExampleOne exampleOne
@Spy
ExampleTwo exampleTwo = new ExampleTwo();
@Spy
ExampleThree exampleThree = new ExampleThree();
@Test
void test(){
exampleOne.doSomethingOne();
//some testing code here
}
}
答案 0 :(得分:1)
通过构造函数注入或方法注入实践显式依赖性原则。接下来,应该分离单元测试。在这种情况下,您不需要访问实现问题。您的类与实现问题紧密相关,而不是代码气味的抽象。
public class ExampleOne {
ExampleTwo exampleTwo;
@Inject
public ExampleOne(ExampleTwo exampleTwo) {
this.exampleTwo = exampleTwo;
}
//implementations below
public void doSomethingOne(){
exampleTwo.doSomethingTwo();
}
}
public interface ExampleTwo {
void doSomethingTwo();
}
public class ConcreteExampleTwo implements ExampleTwo {
private ExampleThree exampleThree;
@Inject
public ConcreteExampleTwo(ExampleThree exampleThree) {
this.exampleThree = exampleThree;
}
public void doSomethingTwo(){
exampleThree.doPrintHello();
}
}
public interface ExampleThree {
void doPrintHello();
}
//...code removed for brevity
ExampleOne
在该级别有一个依赖项,如果这些依赖项无法模拟/存根/伪造而没有副作用,那么目标类的设计就会出现问题。
@RunWith(MockitoJUnitRunner.class)
public class TestExamples(){
@Mock
ExampleTwo exampleTwo;
@InjectMocks
ExampleOne exampleOne
@Test
void test(){
exampleOne.doSomethingOne();
verify(exampleTwo).doSomethingTwo();
}
}
通过上述建议的更改ExampleOne
可以单独测试,而不会产生任何影响。
ExampleTwo
的具体实现也可以单独测试。