简体   繁体   English

Mockito我如何模拟这种方法?

[英]Mockito how do I mock this method?

I am new to mocking and so I'm playing around with this scenario. 我是新手,所以我正在玩这种情况。 I have a method MyClass.process() which calls MyClass.getFactory() . 我有一个方法MyClass.process() ,它调用MyClass.getFactory() I want to mock getFactory() to fail so that I can assure process() recovers correctly. 我想模拟getFactory()失败,以便确保process()可以正确恢复。

It seems that if I call getFactory() after the mock it throws the exception correctly, but if it is called through the original process() method the exception is not thrown. 看来,如果我在模拟之后调用getFactory() ,它将正确引发该异常,但是如果通过原始process()方法对其进行调用,则不会引发该异常。

public class MyClass {

    public MyFactory getFactory() throws FactoryException {
        return ...
    }

    public String process() {
        try {
            MyFactory factory = getFactory();
            ...
        }
        catch(FactoryException ex) {
            ...
        }
    }

}

Test class: 测试类别:

public class MyClassTest {

    @Test
    public void testGetFactoryFails() {
        try {
            MyClass mockMyClass = mock(MyClass.class);
            when(mockMyClass.getFactory()).thenThrow(new FactoryException());
            mockMyClass.process();
            fail("FactoryException should have been thrown.");
        }
        catch(FactoryException ex) {
            // all good
        }
    }

}

Thanks for all the feedback. 感谢您的所有反馈。 I can see how mocking single methods under more complex environments would quickly become unmanageable. 我可以看到在更复杂的环境下模拟单个方法将很快变得难以管理。 The contents of getFactory() is not important as this is concept code, not production code. getFactory()的内容并不重要,因为这是概念代码,而不是生产代码。

One way I tried that works well: 我尝试过的一种方法效果很好:

public class MyClassTest {

    class MyClassMock1 extends MyClass {

        @Override
        public MyFactory getFactory() throws FactoryException {
            throw new FactoryException("Bad factory instance.");
        }

    }

    @Test
    public void testGetFactoryFails() {
        try {
            MyClassMock1 mockMyClass = new MyClassMock1();
            mockMyClass.process();
            fail("FactoryException should have been thrown.");
        }
        catch(FactoryException ex) {
            assertEquals("Bad factory instance.", ex.getMessage());
        }
    }

}

I'll expand what @Can't Tell already said. 我将扩展@ Ca n't Tell已经说过的内容。 You use mocking library to mock dependencies of a class under test. 您可以使用模拟库模拟被测类的依赖关系。 In your case you test MyClass and during tests you should mock all the dependencies (classes that MyClass uses). 在您的情况下,您测试MyClass并且在测试期间应模拟所有依赖项( MyClass使用的类)。

You want to mock a single method in one class and test another method. 您想在一个类中模拟一个方法并测试另一个方法。 While this might be technically possible (but due to various proxying/wrapping mechanics it doesn't work for you), it's certainly a bad design. 尽管从技术上讲这可能是可行的(但是由于各种代理/包装机制,它对您不起作用),但这肯定是一个糟糕的设计。

Show us your getFactory() method. 向我们展示您的getFactory()方法。 If it handles the whole work alone, extract it to a separate class and mock it. 如果它仅处理整个工作,则将其提取到单独的类中并进行模拟。 If it only delegates to another class, mock that one. 如果它仅委托给另一类,则模拟该类。 Sadly, this extracted class will be named... MyFactoryFactory ... 可悲的是,这个提取的类将被命名为... MyFactoryFactory ...

Once you get your dependency extracted, mock it and pass to MyClass before testing (via contstructor, setter...) 一旦提取了依赖项,就对其进行模拟并在测试之前传递给MyClass (通过contstructor,setter ...)

it's because partial mocking is BAD (and that's what you are trying to do). 这是因为部分模拟是错误的(这就是您要尝试的)。 it leads exactly to those kind of problems. 恰恰导致了这类问题。 it's introduced mainly for legacy systems testing. 它主要用于遗留系统测试。 if you write new code and you have to use partial mocking this mean you most probably have bad system design. 如果您编写新代码并且必须使用部分模拟,则意味着您很可能具有不良的系统设计。

you should make getFactory delegate the invocation to some other service (injected into MyClass ) and then you should mock the whole service 您应该让getFactory将调用委托给其他服务(注入MyClass ),然后模拟整个服务

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM