【问题标题】:Mocking two objects of the same type with Mockito使用 Mockito 模拟两个相同类型的对象
【发布时间】:2013-03-18 19:23:42
【问题描述】:

我正在使用 Mockito 编写单元测试,但在模拟注入的类时遇到问题。问题是两个注入的类是相同的类型,并且仅通过它们的@Qualifier 注释来区分。如果我试图简单地模拟SomeClass.class,则不会注入该模拟,并且在我的测试中该对象是null。我怎样才能模拟这些对象?

public class ProfileDAL {

    @Inject
    @Qualifier("qualifierA")
    private SomeClass someClassA ;

    @Inject
    @Qualifier("qualifierB")
    private SomeClass someClassB ;

    //...various code, not important
}

@RunWith(MockitoJUnitRunner.class)
public class ProfileDALLOMImplTest {

    @InjectMocks
    private ProfileDALLOMImpl profileDALLOMImpl = new ProfileDALLOMImpl();

    @Mock
    private SomeClass someClassA;
    @Mock
    private SomeClass someClassB;

    private SomeResult mockSomeResult = mock(SomeResult.class);

    @Test
    public void testSomeMethod() {
        when(someClassA .getSomething(any(SomeArgment.class)).thenReturn(mockSomeResult);
        Int result = profileDALLOMImpl.someTest(This isn't relevant);
    }

 }

【问题讨论】:

  • 你的测试代码是什么样子的?我总是明确地调用Mockito.mock(SomeClass.class) 来创建我的模拟,将注释提供的任何魔法都排除在我的单元测试之外。如果您通过构造函数或设置器注入依赖项,您应该也可以这样做。有充分的理由不是这样吗?
  • 您能否演示在不使用@InjectMocks 的情况下注入这些依赖项?我更新了我的 Q 以展示我的测试是如何设置的。
  • 当所有希望都失败时,您可以随时使用 powermock 注入私有字段。以下链接后面有明确的指南:stackoverflow.com/questions/36173947/…

标签: mockito


【解决方案1】:

我尝试使用 JUnit 使用 Mockito 1.9.5 模拟两个具有相同类型的对象,并且它可以工作。

见:http://static.javadoc.io/org.mockito/mockito-core/1.9.5/org/mockito/InjectMocks.html

文档中的相关类型信息:

"字段注入;mocks会先按类型解析,如果有多个属性同类型,则通过字段名和mock名匹配。"

这似乎是说,当您有两个相同类型时,您应该使模拟名称与所有模拟的字段名称匹配:

“注意1:如果你有相同类型(或相同擦除)的字段,最好用匹配的字段命名所有@Mock注解的字段,否则Mockito可能会混淆并且不会发生注入。”

也许是后者在咬你?

【讨论】:

    【解决方案2】:

    刚刚确认了 Splonk 指出的内容,它在 Mockito 1.9.5 中以这种方式工作,一旦我删除了一个模拟类,它就失败了。

    因此,在您的情况下,请确保您的两个模拟类与您的测试中的类同名:

    @Mock
    private SomeClass someClassA;
    @Mock
    private SomeClass someClassB;
    

    【讨论】:

      【解决方案3】:

      如果你不使用注释,你会得到类似的东西

      public class MyClass {
          private MyDependency myDependency;
      
          public void setMyDependency(MyDependency myDependency){
              this.myDependency = myDependency;
          }
      }
      

      import org.junit.Before;
      import org.junit.Test;
      
      import static org.mockito.Mockito.*;
      
      public class MyTest {
      
          private MyClass myClass;
          private MyDependency myDependency;
      
          @Before
          public void setUp(){
              myClass = new MyClass();
              myDependency = mock(MyDependency.class);
              myClass.setMyDependency(myDependency);
          }
      
          @Test
          public void test(){
              // Given
      
              // When
      
              // Then
          }
      }
      

      如果您的对象的依赖项是通过构造函数而不是通过 setter 指定的,那么您也可以这样做。我猜你的依赖注入框架可以像注释私有字段一样注释设置器,但是现在你的测试不依赖于任何依赖注入框架。

      【讨论】:

      • 我无法拒绝使用依赖注入框架。这是一个不在我手中的设计决定。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多