如何使用 Guice @Inject 模拟一个对象?

How to mock an object with Guice @Inject?

我有一个 class A 和一个 class B。

public class A{
    @Inject // Guice Inject
    private B b;
}

测试class看起来像-

public class ATest{
    private B b;
    
    private A a;

    @Before
    public void setup() {
        b = Mockito.mock(b.class);
        a = new A();
    }
}

问题是 class B 没有被嘲笑。在测试 class 中,每当调用 B 的方法时都会出现 NullPointerException。我无法更改 class A。请帮我看看如何成功模拟 class B?

我假设在你的情况下不是 B 没有被模拟,而是它没有被注入 a

注入它的一种方法是在测试中创建一个带有 Module 的 Guice Injector,这将绑定要注入的 Class,B 在你的情况下,到 B 的具体实例,然后使用 Injector#injectMembers(a) 将 b 注入 a.

工作示例:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;

class InjectableTest {
  private static class Service {
    @Inject
    private Object obj;

    public Object getObj() {
      return obj;
    }
  }

  private final Object obj = Mockito.mock(Object.class);
  private final Injector injector = Guice.createInjector(new AbstractModule() {
    @Override
    protected void configure() {
      bind(Object.class).toInstance(obj);
    }
  });

  @Test
  void t() {
    Service s = new Service();
    injector.injectMembers(s);
    Assertions.assertEquals(obj, s.getObj());
  }
}

如果您需要比一次测试更频繁地执行此操作,请查看 this 问题的答案,其中讨论了单元测试中 Guice 依赖注入的不同方式。