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

验证是否调用了方法并中断执行/忽略以后的失败

  •  1
  • oligofren  · 技术社区  · 7 年前

    我有一个测试,我已经编写了我需要的大部分单元测试,但是有一个我想测试逻辑的第一部分。只要方法被调用,我不在乎在方法的其余部分会发生什么,但是由于sut由于缺少进一步的模拟而在npe中失败,所以在我得到断言之前测试失败了。

    有没有 清洁的 断言一个方法的方法被调用并忽略之后发生的所有异常?也许是在命中方法并在之后中止/通过测试时的某种阻塞行为?

    我想我可以写 when(mock.methodIAmInterestedIn(any)).thenThrow(new RuntimeException("verified!")) 然后简单地断言我得到了正确的异常(不过,它将被包装在另一个异常中)。这可能行得通,但有点不干净:模糊了我真正想测试的东西。

    @Test
    public void should_load_using_filename_in_config() {
        loader = new OrgUnitLoader(config, dbSupport.mockServices);
        config = mock(TestConfiguration.class);
        /* further mocking of the config needed if I am not to get an NPE */
    
        when(dao.orgUnitsAreLoaded()).thenReturn(false);
    
        // call the actual method
        loader.loadOrgUnits();
    
        verify(config, times(1)).getString(ORG_UNIT_DATA_FILE);
    }
    

    可能会 CountdownLatch 例如,被使用?

    3 回复  |  直到 7 年前
        1
  •  2
  •   Timothy Truckle Vincent Boutot    7 年前

    我想测试逻辑的第一部分。我不在乎其他方法会发生什么

    这看起来像你的 测试中的代码 失败了 单一责任模式 .

    您可能更愿意将该方法的独立部分提取为单独的方法,甚至更好地提取为它们自己的对象。结果你现在的方法会变成 组成 方法,该方法使用一些具有非常小的逻辑且易于测试的依赖项。


    有两个明显的缺点:

    1. 然后,我需要打开sut,将许多自然应该是私有的内部方法创建成具有包访问权限的方法,以便能够测试它们。寡聚酮

    关键是有一个obvoius需要验证 调度行为 独立于当前方法中填充的实际业务逻辑。 这告诉我 调度行为 是它自己的责任,应该与其他的或方法分开。

    在我看来,所有其他逻辑都属于其他类,而不仅仅是同一类中的单独方法。 这是由于 同一抽象层次 我们应该应用于类和方法的原则。这种新的类确实至少可以提供 package private 访问他们的界面。

    1. 我会非常紧密地与sut的内部联系在一起,但我想我已经这样做了……寡法语

    这种“紧密绑定”可能只存在于知道实际实现的头脑中。 事实上,您需要分割代码以进行测试,这表明代码不像您想象的那样有太多的限制。

    我想在所有的单元测试决策(只测试代码,开放,…)中都会涉及到一些实用主义。寡聚酮

    关于单元测试有一个非常简单的规则,它避免了所有那些“务实的决定”的东西:

    单元测试不测试 代码 ,单元测试验证 公众可观察行为 哪里 公众的 手段: 返回值 与依赖项的通信 .

    没有“务实决定”的余地。唯一的决定是: 削减的预期行为是什么 ?

        2
  •  0
  •   YohanT    7 年前

    为什么你不使用 CompletableFuture ,您可以使用无参数构造函数创建此类的实例来表示将来的某些结果,将其分发给使用者,并在将来的某个时间使用complete方法完成它。使用者可以使用get方法阻塞当前线程,直到提供此结果为止。

        3
  •  0
  •   LuCio    7 年前

    因为您知道您的测试加载程序/配置不完整,所以您希望该方法在某个时候失败。在你的测试中考虑一下:

    @Test
    public void should_load_using_filename_in_config() {
        loader = new OrgUnitLoader(config, dbSupport.mockServices);
        config = mock(TestConfiguration.class);
        /* further mocking of the config needed if I am not to get an NPE */
    
        when(dao.orgUnitsAreLoaded()).thenReturn(false);
    
        try {
            // call the actual method
            loader.loadOrgUnits();
            Assert.fail("Should fail as config is incomplete.");
        } catch (NullPointerException e) {
            verify(config, times(1)).getString(ORG_UNIT_DATA_FILE);
        }
    
    }
    

    编辑(以下注释)

    仅捕获预期的npe会排除其他异常。是否应该在 dao.orgUnitsAreLoaded() 被称为 verify(...) 会失败。你会注意到的。

    也许这不是很复杂,但很简单( )去理解-甚至以后被别人理解。

    参见 Junit assert something after awaiting and handling an exception