代码之家  ›  专栏  ›  技术社区  ›  DaeYoung

当您在mockito框架中模拟一个类时,您是否手动地站起来模拟实际的类?

  •  -2
  • DaeYoung  · 技术社区  · 6 年前

    我对Mockito框架还比较陌生。我一直在阅读关于它的多个教程。我跟踪的其中一个是: https://www.tutorialspoint.com/mockito/mockito_first_application.htm

    有一个声明创建了一个模拟股票服务。

    In this example, we've created a mock of Stock Service to get the dummy price of some stocks

    我的问题是 Stock Service a real service class mock service class 你必须手动站起来模仿真正的服务类。我有点困惑。对JUnit框架有基本了解。我以前练习过的是如果有一个服务班 Foo 然后我使用了提供所有公开方法的实际类。

    public class Foo {
    
        public Foo() { } // construtor
    
        public String returnAddress(String userId) {
            // ...
            return dataAccesobj.getAddress(userId);
        }
    }
    

    打电话 foo.returnAddress(..) 在单元测试中,如果我记得对的话。

    我问这个问题的原因是在我工作的时候 mockito 为了创建类的测试方法,我遇到了一个唯一的(?)挑战。

    我从一个真正的服务类开始,它依赖于它的超类构造函数来返回它的实例。我遇到的挑战是这个超级类构造函数启动数据库连接,并加载/解析我的测试不需要的属性文件。我在考虑如何防止数据库连接和加载/读取prop文件…

    我以为我读过 莫基托 教程可以隔离测试,而不需要这样的服务。我尝试过 @Mock @Spy (仍然不完全理解它们的用途……)但是它对输出没有影响(也许我误用了那些注释)。

    所以我所做的实际上是在真正的服务类(例如 )只需复制它并将其重命名为 FooMock 把它放进去 src/test/java 运行单元测试类的文件夹。我保持模拟类和真正的服务类完全相同,只是去掉了不需要的逻辑,例如 db connection loading/reading prop file for env specific . 通过这样做,我可以测试一个读取LDAP目录的公开方法…

    很抱歉我被挖苦了,但希望我的观点在这一点上是明确的。我不确定我处理这种情况的方式是对还是错。我希望有经验的工程师能澄清我处理这件事的方式是可以接受的。 莫基托 不管是不是。如果没有,请告诉我最好的处理方法。

    1 回复  |  直到 6 年前
        1
  •  0
  •   DwB    6 年前

    和Mockito一起, 模拟是包装类的实现。 模拟对象“包装”模拟对象的目标 (示例中的服务) 并允许您定义每个方法的功能。

    Mockito有两个模拟功能选项; 调用包装方法,不要调用包装方法。

    我不知道什么时候调用包装方法才有意义, 所以我总是使用不调用包装方法。

    在你制作了模型之后, 使用mockito.doreturn(返回值).when(mockobject).method(方法参数)方法模拟功能。

    编辑:更多信息。

    我假设您使用的是JUnit v4。 根据JUnit的主要版本号,这方面的细节会有所不同, 但实际工作是一样的。

    1. 使用注释定义模拟对象( @Mock ),请 除了一些特殊情况。 这将创建非最终类的模拟, 抽象类, 和接口。
    2. 使用创建“测试前”方法 @Before 注释; 我传统上叫这个方法 preTestSetup , 但真正的名字并不重要。
    3. 呼叫 MockitoAnnotations.initMocks(this) 作为第一行代码 在“试验前”方法中。 这将找到 嘲讽 注释并为每个实例实例化一个模拟。
    4. 使用 ReflectionTestUtils.setField 方法将模拟注入到对象中(假设您没有setter方法, 传统上我不喜欢)。
    5. 使用定义每个方法的模拟功能 Mockito.doReturn(returnvalue).when(mockObject).method(method parameters) 技术。

    下面是一些示例代码 (警告: 这应该是完全正常的, 但我没有编译它):

    public interface MyService
    {
        String blammy(SomeParameter parameter);
    }
    
    public class UsesMyService
    {
        @Autowired
        private MyService myService;
    
        public String kapow(final SomeParameter parameter)
        {
            return myService.blammy(parameter);
        }
    }
    
    public class UnitTestUsesMyService
    {
        private UsesMyService classToTest;
    
        @Mock
        private MyService mockMyService;
    
        @Mock
        private SomeParameter mockSomeParameter;
    
        @Before
        public void preTestSetup()
        {
            MockitoAnnotations.initMocks(this);
    
            classToTest = new UsesMyService();
    
            doReturn("Blam").when(mockMyService).blammy(mockSomeParameter);
    
            ReflectionTestUtils.setField(
                classToTest,
                "myService",
                mockMyService);
        }
    
        @Test
        public void kapow_allGood_success()
        {
            final String actualResult;
    
    
            actualResult = classToTest.kapow(mockSomeParameter);
    
    
            assertNotNull(actualResult); // Not strictly necessary.
    
            assertEquals(
                "Blam",
                actualResult);
        }
    }