在 Guice 中为 Map 注入编写单元测试

Writing unit test for Map injection in Guice

我是 Guice 新手。我写了以下 class,它依赖于通用映射,它是 managerMap,它将对象类型映射到负责处理该类型对象的特定管理器。

public class MyClass<T extends MyClass> {

    @Inject
    @Named("ManagerMap")
    private Map<String, Manager> managerMap;

    @Override
    public void myFunc(@NotNull T myObj) {
        Manager manager = managerMap.get(myObj.getClass().getName());
        manager.call(myObj);
    }
}

以上代码 运行 没问题。现在我想为上面编写单元测试。我写的像下面这样,它正在工作,但我认为有更好的方法来做到这一点。

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

    @InjectMocks
    private MyClass myclass;

    @Mock
    private Map<String, Manager> managerMap;

    private final MyClass1 myObj;     <--MyClass1 extends from MyClass

    @Test
    public void testmyFunc() {
        Mockito.when(managerMap.get(myObj.getClass().getName())).thenReturn(new MyManager1());
        myclass.myFunc(myObj);
    }
}

"best" 做事的方式是个人喜好问题,所以对 SO 来说不是一个好问题。

但这就是我编写代码的方式:

public class MyClass<T extends MyClass> {

    private final Map<String, Manager> managerMap;

    @Inject // constructor injection
    @Named("ManagerMap")
    public class Myclass(Map<String, Manager> managerMap) {
        this.managerMap = managerMap;
    }

    @Override
    public void myFunc(@NotNull T myObj) {
        Manager manager = managerMap.get(myObj.getClass().getName());
        manager.call(myObj);
    }
}

测试

public class MyClassTest {

    private MyClass myclass;

    @Test
    public void testmyFunc() {
        // prepare map
        Map<String, Manager> managerMap = new HashMap();
        MyManager1 = myManager new MyManager1()
        managerMap.put(myObj.getClass.getName(), myManager);

        // create class under test with injected map
        myclass = new MyClass(managerMap);

        myclass.myFunc(myManager);
    }
}

所以通过使用Constructor注入和普通的HashMap,测试代码变得干净多了,被测的class也差不了多少。这里不需要 Mockito。

如果您确实想传入 Manager Mock,您可能需要 Powermock,例如 this question 中的 Powermock 来模拟 getClass() 调用。