复杂的Junit测试用例

htrmnn0y  于 11个月前  发布在  其他
关注(0)|答案(4)|浏览(238)

我正在尝试为这个类创建一个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);
        }

字符串

pdtvr36n

pdtvr36n1#

import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
@ExtendWith(MockitoExtension.class)
    class ObjectClaimHistoryTest {
    private int colId = 1001;
    private Set<Integer> out = Set.<Integer>of(1, 2, 3);
    private ObjectClaimHistory objectClaimHistory = new ObjectClaimHistory();

    @Test
    void test(@Mock ClaimRequest cr, @Mock ClaimConflicts cc,
            @Mock ObjectCollaborationClaimHistory objectCollaborationClaimHistory) {
        ReflectionTestUtils.setField(objectClaimHistory, "objectClaimHistory",
                List.of(objectCollaborationClaimHistory));
        when(objectCollaborationClaimHistory.getCollaborationId()).thenReturn(1001);
        objectClaimHistory.checkClaim(cr, out, colId, cc);
        when(objectCollaborationClaimHistory.checkClaim(eq(cr), eq(out))).thenReturn(true);
        when(objectCollaborationClaimHistory.checkBlock(eq(cr), eq(out))).thenReturn(true);
        objectClaimHistory.checkClaim(cr, out, colId, cc);
        when(objectCollaborationClaimHistory.checkBlock(eq(cr), eq(out))).thenReturn(false);
        objectClaimHistory.checkClaim(cr, out, colId, cc);
    }

}

字符串

holgip5t

holgip5t2#

如果我没理解错的话...
您希望控制collaborationClaimHistory示例的行为,以便在某些测试场景中它返回true,而在其他测试场景中它返回false:

  • collaborationClaimHistory.checkClaim(claimRequest, outOfDateCommits)
  • collaborationClaimHistory.checkBlock(claimRequest, outOfDateCommits)

您想要Assert添加到给定ClaimConflicts的commitConflicts是有效的。
查看代码,我看到了这个:for (ObjectCollaborationClaimHistory collaborationClaimHistory : objectClaimHistory),这让我怀疑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
}

字符串

dohp0rv5

dohp0rv53#

要检查每个if和else if语句,您需要创建多个单元测试,并为每个if和else if语句预期的每个情况传递一个参数,即您将为方法创建4个测试用例,并给予4个参数。另一种不推荐的测试方法是在每个if和else if语句中添加assertTrue语句,这是一种糟糕的测试方法,但非常快速和简单。我将检查输入是否给出,并在运行时是正确的。让我知道,如果你需要任何更多的帮助或示例代码

pgky5nke

pgky5nke4#

1.利用setup(@Before)方法来创建一个健壮的测试夹具,模拟依赖于外部资源的协作者,例如DB,Queue。在测试类中创建成员变量来容纳测试协作者,并在setup方法中设置它们的状态。这使测试方法能够根据给定测试的需要更改它们。
1.在每一个测试中,如果有必要的话,可以改变测试夹具来满足测试的条件。因为测试只会因为一个原因而失败,所以你最好只改变测试夹具的一个方面。一个经过深思熟虑的测试夹具可以很好地防止由于不完整的测试设置而导致的意外的副作用。剩下的就是调用被测单元并Assert预期的结果。
1.使用代码覆盖率工具来跟踪你的进度。你会惊讶于你为一个生产方法写了多少次太多的测试。
如果你遵循这种方法,设置fixture会花费更长的时间,但是测试本身中的重复代码会更少。回报是,一旦fixture被设置好,测试通常会很短,很快就完成了,并且为将来添加更多的测试打下了良好的基础。

相关问题