繁体   English   中英

如何使用 JUnit Mockito 验证未调用方法

[英]How to check that a method is not being called using JUnit Mockito Verify

我有一个正在为其编写 JUnit 测试的类。 我正在尝试测试是否从未调用过特定方法。

public class CountryProcess extends AbstractCountryProcess {

    private static final Logger log = LoggerFactory.getLogger(CountryProcessor.class);
    private static final Long MAX_FILE = 20l;

    @Override
    protected boolean processCountry(Region region, City city) {
        Long maxFile = region.getRequiredLongValue(SIZE);

        if (maxFile < MAX_FILE) {
            cntDao.addCountryLandMark(city);
        }
        else {
            log.warn("File size was big");
        }

        return true;
}

测试类是:

public class CountryProcessTest {

    @Rule
    public final JUnitRuleMockery context = new JUnitRuleMockery();
    private final CntDao cntDao = context.mock(CntDao.class);

    @Before
    public void setup() {
        Injector injector = Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                bind(cntDao.class).toInstance(cntDao);
            }
        });
    }

    @Test
    public void shouldIgnoreIfFileSizeBiggerThanPermitted() {
        //some code to make it trigger ELSE statement above...
        verify(cntDao, never()).addCountryLandMark(anyString());
    }
}

但这会返回以下错误:

org.mockito.exceptions.misusing.NotAMockException:

传递给 verify() 的参数属于 $Proxy4 类型,不是模拟!

确保正确放置括号!

请参阅正确验证的示例:

验证(模拟)。someMethod();

验证(模拟,次(10))。someMethod();

验证(模拟,atLeastOnce())。someMethod();

知道如何在当前上下文中解决此问题。 请举一个使用当前代码的例子,以便我得到更好的主意?

您正在混合两个模拟框架:

  • jMock- JUnitRuleMockery
  • Mockito- verify方法

显然,它们彼此不兼容。 您的验证调用看起来还不错,我相信它会在收到使用Mockito.mock(CntDao.class)创建的模拟文件后立即运行(使用Mockito.mock(CntDao.class)

作为never替代的选择,您可以使用Mockito.verifyNoMoreInteractionsMockito.verifyZeroInteractions ,但是它们的具体性较低。

除了@Lesiak 的回答之外,这里还有一个基于您的代码的可重现示例,其中包含测试条件和 BDD 实现(已注释掉)。

@ExtendWith(MockitoExtension.class)
class CountryProcessTest {

    @Mock CountryDAO cntDao;

    @Mock
    Region region;

    @Mock
    City city;

    @InjectMocks
    CountryProcess countryProcess;


    @Test
    void processCountryLargeSize() {
        // given
        given(region.getRequiredLongValue()).willReturn(100L);

        // when
        countryProcess.processCountry(region, city);

        // then
        verifyNoInteractions(cntDao);
        // then(cntDao).shouldHaveNoInteractions(); // BDD implementation
    }

    @Test
    void processCountrySmallSize() {
        // given
        given(region.getRequiredLongValue()).willReturn(10L);

        // when
        countryProcess.processCountry(region, city);

        // then
        verify(cntDao).addCountryLandMark(city);
        verifyNoMoreInteractions(cntDao);
        // then(cntDao).should().addCountryLandMark(any()); // BDD implementation
        // then(cntDao).shouldHaveNoMoreInteractions(); // BDD implementation


    }
}

此处提供其余类以供参考。

地区

public class Region {

    private int size;

    public Long getRequiredLongValue() {

        return Integer.toUnsignedLong(size);
    }
}

抽象国家进程


public abstract class AbstractCountryProcess {

    CountryDAO cntDao;

    protected abstract boolean processCountry(Region region, City city);
}

暂无
暂无

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

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