Java 如何模拟@Inject接口

Java 如何模拟@Inject接口,java,unit-testing,junit,mockito,Java,Unit Testing,Junit,Mockito,我有这个服务接口 public interface ABC { public String getAbc(); } 我有一个使用这个服务的控制器 public class Do { @Inject ABC abc; public String doAbc() { String a = abc.getAbc(); } } 在我的单元测试中,我希望能够模拟这个ABC,而不必提供实际的实现。以下是有效的方法: public class TestDo

我有这个服务接口

public interface ABC {
    public String getAbc();
}
我有一个使用这个服务的控制器

public class Do {
    @Inject ABC abc;

    public String doAbc() {
       String a = abc.getAbc();
    }
}
在我的单元测试中,我希望能够模拟这个ABC,而不必提供实际的实现。以下是有效的方法:

public class TestDo {
   @Mock
   private Do do;

   @Mock
   private ABC abc;

   @Before
   public void init() {
       MockitoAnnotations.initMocks(this);
       do.abc = abc;
   }

   @Test
   public void testDo() {
       when(do.doAbc()).thenCallRealMethod();
       do.doAbc();
       assertSomething...
   }
}

但是我不想做的是
do.abc=abc,从我所有的搜索中,为了执行@InjectMock,我需要提供一个具体的类。有没有一种方法可以让我使用这个接口,但却能够将模拟接口注入do,而无需在do类中公开我的ABC Inject?我想使ABC成为一个私有变量,并且仍然能够通过Mockito注入接口。

您给出的示例是构造函数注入的完美案例:您可以将依赖项设置为私有(甚至是最终的,在实际情况下这是最好的),并且仍然构建实例,而不需要注入框架:

public class Do {
    private final ABC abc;

    @Inject
    public Do(final ABC abc) {
        this.abc = abc;
    }

    public String doAbc() {
       String a = abc.getAbc();
    }
}
输出为:

Injected abc is not null
null

我不想把ABC全部曝光。我想做
@injectprivate-ABC
@Churk您的
ABC
是一个依赖项。你的
Do
类必须拥有它。使用字段注入来隐藏依赖关系只会使以后的事情更容易崩溃——此外还会使测试更加困难。DI的全部目的是通过使其显式化来删除神奇的依赖项。它不是隐藏依赖项,但在我的实际使用中,它是一个DataAccessService,我不希望任何人能够直接访问此服务。这就是为什么我希望它是私有的。@Churk听起来好像你不明白Java访问修饰符是用来做什么的。DI系统必须具有对服务的访问权限才能注入服务,因此,使用构造函数注入不会暴露任何额外内容。如果我错了,请纠正我,您的构造函数允许此
Do=new Do(myABC),现在是安全性问题,我只是告诉我的应用程序允许构建此服务的人注入他们自己的ABC类。Vs
@injectprivate ABC
,我的构造函数不接受任何ABC类,强制只在spring级别执行注入。那么,我是理解java访问,还是需要进一步解释?@Churk用Mockito 1.9.5和JDK 1.8测试了它。一切顺利。我会将我的答案更新为完整的工作代码。我会重新阅读你的代码。我的错误是,我在实际代码中使用了/@injectmock,这相当于ABC,因此,它试图创建一个接口的实例,这让我很失望。并且将/@Mock设置为等同于做什么,所以我的Mock和injectmock是向后的。
Injected abc is not null
null