复杂的Junit测试案例

时间:2017-07-11 15:10:11

标签: java unit-testing testing junit

我正在尝试为这个类创建一个JUnit测试。

测试不同的if-else语句的最佳方法是什么。

我尝试了一些通用的单元测试用例。

public class ObjectClaimHistory {

    private List<ObjectCollaborationClaimHistory> objectClaimHistory = new ArrayList<>();

    public void checkClaim(ClaimRequest claimRequest, Set<Integer> outOfDateCommits, int collaborationId, Integer parentCollaborationId, ClaimConflicts conflicts) {
        Set<Integer> conflictingCollaborationClaims = new HashSet<>();
        Set<Integer> conflictingCollaborationBlocks = new HashSet<>();
        for (ObjectCollaborationClaimHistory collaborationClaimHistory: objectClaimHistory) {
            if (!collaborationClaimHistory.checkClaim(claimRequest, outOfDateCommits)) {
                conflictingCollaborationClaims.add(collaborationClaimHistory.getCollaborationId());
            }
            if (!collaborationClaimHistory.checkBlock(claimRequest, outOfDateCommits)) {
                conflictingCollaborationBlocks.add(collaborationClaimHistory.getCollaborationId());
            }
        }
        // After checking all histories create one commit conflict. Choose the closest collaboration.
        if (conflictingCollaborationClaims.contains(collaborationId)) {
            conflicts.addCommitConflict(claimRequest.getObjectId(), claimRequest.getClaim(), collaborationId);
        }
        else if (conflictingCollaborationBlocks.contains(collaborationId)) {
            conflicts.addCommitConflict(claimRequest.getObjectId(), claimRequest.getBlock(), collaborationId);
        }

3 个答案:

答案 0 :(得分:0)

要检查每个if和else if语句,您需要创建多个单元测试,并为每个if和else if语句预期的每个案例传入一个参数,即您将为您的方法创建4个测试用例并给它4参数。测试哪种不推荐的另一种方法并且是一种不好的方法但是非常快速和简单的是在每个if和else if语句中添加assertTrue语句,这将检查输入是否在运行时是否正确。如果您需要更多帮助或示例代码,请告诉我们

答案 1 :(得分:0)

如果我理解你的问题那么......

您希望控制save()实例的行为,以便在某些测试方案中它返回true,而在其他情况下,它会为这些调用返回false:

  • collaborationClaimHistory
  • collaborationClaimHistory.checkClaim(claimRequest, outOfDateCommits)

您想声明添加到给定collaborationClaimHistory.checkBlock(claimRequest, outOfDateCommits)的commitConflicts是有效的。

查看代码,我看到了这一点:ClaimConflicts这让我怀疑for (ObjectCollaborationClaimHistory collaborationClaimHistory : objectClaimHistory)是以objectClaimHistory注入或发现的ObjectClaimHistory。对于您的测试,您必须能够控制填充的方式,以便返回CollaborationClaimHistory的实例,您可以调整这些实例以满足您的测试场景。

以下是一个假设在创建objectClaimHistory时注入ObjectClaimHistory的示例:

@Test
public void someTest() {
    CollaborationClaimHistory collaborationClaimHistory = Mockito.mock(CollaborationClaimHistory.class);

    ObjectClaimHistory sut = new ObjectClaimHistory(Lists.newArrayList(collaborationClaimHistory));

    ClaimRequest claimRequest = ...;
    Set<Integer> outOfDateCommits = ...;
    int collaborationId = ...;
    Integer parentCollaborationId = ...;
    ClaimConflicts conflicts = ...;

    // set up expectations on the collaborationClaimHistory instance which will be interrogated within the sut
    Mockito.when(collaborationClaimHistory.checkClaim(claimRequest, outOfDateCommits)).thenReturn(true);

    sut.checkClaim(claimRequest, outOfDateCommits, collaborationId, parentCollaborationId, conflicts);

    // assert that the response (which is implicit in th post invocation state of conflicts) is valid
    assertTrue(conflicts.hasCommitConflict(claimRequest.getObjectId(), claimRequest.getClaim(), collaborationId));

    // ... and repeat for other scenarios, multiple CollaborationClaimHistory instances etc
}

答案 2 :(得分:0)

  1. 利用setup(@Before)方法创建一个强大的测试工具,模拟依赖外部资源的协作者,例如DB,Queue。在测试类中创建成员变量以保存测试协作者并在setup方法中设置其状态。这使测试方法能够根据给定测试的需要更改它们。

  2. 在每次测试中,必要时更换测试夹具以达到满足测试条件的要求。由于测试只会因某种原因失败,因此理想情况下,您只需更改测试夹具的一个方面。经过深思熟虑的测试夹具可以很好地防止因不完整的测试设置而导致的意外副作用。剩下的就是调用被测单元并断言预期结果。

  3. 使用代码覆盖率工具跟踪进度。你为生产方法编写了太多的测试,你会感到惊讶。

  4. 如果你采用这种方法,设置灯具需要更长的时间,但测试本身的重复代码会更少。奖励是,一旦设置了夹具,测试通常很短,很快完成,并为将来添加更多测试奠定了良好的基础。