【问题标题】:Mocked method returns actual value instead of the mocked one模拟方法返回实际值而不是模拟的
【发布时间】:2016-09-06 09:32:15
【问题描述】:

我被要求在 Android Studio 上设置持续集成,因此我开始进行单元测试和模拟。

我觉得我误解了 Mockito 的基础和工作原理。我在网上找到了这样的例子:

    @RunWith(MockitoJUnitRunner.class)
    public class ExampleUnitTest {

      MainActivity classToTest = new MainActivity();

      @Mock
      ClassIDontWantToTest classToMock;

      /**
       * Examples found a lot of times on the Internet
       * My method is not tested at all
       * I think it doesn't make sense to test Mockito but our own methods
       * @throws Exception
       */
      @Test
      public void testMethodIDontWantToTest() throws Exception {
        when(classToMock.methodIDontWantToTest()).thenReturn("Mocked result");
        assertTrue(classToMock.methodIDontWantToTest().equals("Mocked result"));
      }

    }

这是我的代码:

    public class MainActivity extends AppCompatActivity {
      ClassIDontWantToTest classIWantToMock = new ClassIDontWantToTest();

      /**
       * Actual Method I want to test
       * @return Return value
       */
      public String methodIWantToTestButReturnsUnspectedValue() {

          //  (...) Code to test

          return classIWantToMock.methodIDontWantToTest();
      }
    }


    public class ClassIDontWantToTest {

      public String methodIDontWantToTest() {
        return "Actual result";
      }

    }

这就是我理解的方式:

    @RunWith(MockitoJUnitRunner.class)
    public class ExampleUnitTest {
      MainActivity classToTest = new MainActivity();

      @Mock
      ClassIDontWantToTest classToMock;

      /**
       * Test I want to do and I think it makes sense, but it doesn't work
       * @throws Exception
       */
      @Test
      public void testMethodIWantToTest() throws Exception {
        when(classToMock.methodIDontWantToTest()).thenReturn("Mocked result");
        assertTrue(classToTest.methodIWantToTestButReturnsUnspectedValue().equals("Mocked result"));
      }
    }

显然有些东西我不明白,但我不知道它是什么。 谁能告诉我哪里错了?

非常感谢!

【问题讨论】:

  • 这是单元测试(在 JVM 中)还是仪器测试(在模拟器中)?另外,ClassIDontWantToTestmethodIDontWantToTest 都是公开的和非最终的,对吧?
  • 据我所知,您还没有将模拟对象注入到您正在测试的类中。我首选的解决方法是向要测试的类添加第二个构造函数,在其中传入 classIWantToMock 的值 - 然后测试已使用第二个构造函数实例化的对象。如果您无法向该类添加第二个构造函数,那么另一种方法是将 @InjectMocks 注释放在测试中的 classToTest 声明上 - 但有时可能会更不稳定。

标签: android unit-testing mockito


【解决方案1】:

您的模拟对象未正确设置,意味着您的 MainActivity classToTest = new MainActivity(); 类未注入 ClassIDontWantToTest classToMock;

要做到这一点,你需要这样的东西:

 @RunWith(MockitoJUnitRunner.class)
 public class ExampleUnitTest {

  @InjectMocks
  MainActivity classToTest;

  @Before
  public void setup() {
   MockitoAnnotations.initMocks(this);
  }

  @Mock
  ClassIDontWantToTest classToMock;

  @Test
  public void testMethodIWantToTest() throws Exception {
   when(classToMock.methodIDontWantToTest()).thenReturn("Mocked result");
   String expected = classToTest.methodIWantToTestButReturnsUnspectedValue();
   assertEquals(expected, "Mocked result");
  }
 }

【讨论】:

    【解决方案2】:

    尤里卡! 正如大卫华莱士所说,我必须在classToTest的声明上加上@InjectMocks注解。

    现在我的测试工作正常,而且很有意义。非常感谢!

    @RunWith(MockitoJUnitRunner.class)
    public class ExampleUnitTest {
    
      @Mock
      ClassIDontWantToTest classToMock;
    
      @InjectMocks
      MainActivity classToTest;
    
      ////////// Test that makes sense and works fine
      @Test
      public void testMethodIWantToTest() throws Exception {
        when(classToMock.methodIDontWantToTest()).thenReturn("Mocked result");
        assertTrue(classToTest.methodIWantToTest().equals("Mocked result"));
      }
    
    }
    
    
    
    ////////////////  Class to mock
    public class ClassIDontWantToTest {
      public String methodIDontWantToTest() {
        return "Actual result";
      }
    }
    
    
    
    
    ////////////// Class to be tested
    public class MainActivity extends AppCompatActivity {
      ClassIDontWantToTest classIWantToMock = new ClassIDontWantToTest();
    
      ////////////  Actual Method I want to test
      public String methodIWantToTest() {
          //  (...) Code to test
          return classIWantToMock.methodIDontWantToTest();
      }
    
    }
    

    【讨论】:

    • 那你应该把这个答案标记为“接受”(或者kuhajeyan的那个,基本一样)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    相关资源
    最近更新 更多