如何彻底测试使用接口的类

时间:2019-02-08 10:21:51

标签: java testing junit cryptography mockito

我实现了一个类,该类使用需要互换的几种不同算法,因此,我使用接口。现在,我想测试我的课程,但是由于我使用了Interfaces,因此无法实例化算法。

独立于接口测试类的最佳方法是什么?在测试中,我想假设每个接口的行为都应该像预期的那样。

背景:

我目前正在从事一个项目,在该项目中,我必须实现使用多个加密原语(例如,签名,Mac等)的加密构造。 此实现的目标是拥有一个不使用特定原语的通用实现,然后实例化这些原语,以使构造真正起作用。

我仅使用接口实现了通用构造。我使用“工厂”来获取特定的原语,到目前为止,一切似乎都很好。但是,当然,我需要测试我的代码。

我进行了一些研究,但不幸的是,我没有找到问题的确切答案(也许是因为我使用了错误的搜索查询)。 人们大多数时候都想测试接口或接口的实现。但这不适用于我的情况。

我了解了Mockito,但是大多数示例都很简单,其中Mockito模拟了一个数据库,而且我不知道Mockito是否仍然是测试我的情况的最佳方法,特别是如果我要模拟使用非对称的签名时键。如果我使用Mockito,我想代码会变得混乱,因为Mockitos声明具有“内联”性质。

Mockito(或一般的Mocks)是否适用于这种测试,还是我必须实现接口的(基本)实现?

示例:

所以我的“主”类具有一个算法集:

AlgorithmSet algorithmSet;

此algorithmSet由AlgorithmFactories组成

HashFactory HashFactory;
SignatureFactory signatureFactory;
SymmetricKeyFactory keyFactory;

在“主”类中,我调用类似于以下算法的函数:

Signature signatureScheme = algorithmSet.getSignatureFactory().getSignature();
SignatureKeyPair keyPair = signatureScheme.generateKey();
SignatureOutput signature = signatureScheme.sign(keyPair.getPrivateKey(), message);

这只是我为解决这个问题而编写的一个小示例,因此我的实际代码看起来有些不同,但这只是要点。

Signature,SignatureKeyPair,SignatureOutput都是接口,因为在我的“主”类中,我不关心它们是否达到了目的。

在我的案例中,测试“主要”课程的最佳方法是什么? Mockito还是最好的方法吗?还是对所有接口进行基本实现以提高可读性更好?共有5种算法(每种算法都有Output,Keys等)。还是我还没有找到另一种方法?

我非常感谢您的每一次帮助,并感谢您的阅读!

2 个答案:

答案 0 :(得分:0)

Mockito是一个优秀的框架,用于存根您的界面。

从概念上讲,存在不同的方法-通常区分为classicalmockist测试。 Martin Fowler Mocks aren't Stubs的文章是对此的经典参考。

答案 1 :(得分:0)

欢迎使用Stackoverflow!

如果我正确理解了您的帖子,则主要问题是要测试Main类。假定您已经成功测试了接口,工厂等的具体实现类。

如果是这样,我建议通过将Main实例的获取提取到单独的方法来重构您的Signature类:

class Main {
    ...

    Signature getSignature() {
        algorithmSet.getSignatureFactory().getSignature();
    }

    Signature signatureScheme = getSignature();

    ...
}

现在在单元测试中,您可以用模拟的实例代替实际的Signature实例。 Mockito很适合这种方式。

class MainTest {
    @Test
    public void testSomething() {
        Signature mockedSignature = Mockito.mock(Signature.class);
        // TODO: define the behavior of the mocked Signature.

        // Given an instance of Main class but with overridden method to get mocked Signature. 
        Main customMain = new Main() {
            @Override
            Signature getSignature() {
                return mockedSignature;
            }
        }

        // When
        customMain.doSomething()

        // Then
        // TODO: validate the actual result and mocks interactions.
    }
}