You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何Mock JGit的git.push()命令?JUnit测试遇异常求助

Mock JGit Push Command for Local Testing

Absolutely, you can mock or bypass the actual remote push operation to run your tests locally without hitting a real remote repository. Here are a few practical approaches tailored to your scenario:

1. Mock the PushCommand Directly with a Mocking Framework (e.g., Mockito)

If you want to completely skip any real Git operations for the push step, use a mocking library to fake the PushCommand behavior. This is perfect for pure unit tests where you just need to verify the push method is called correctly, without executing actual repository logic.

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.mockito.Mockito;

// Mock core JGit objects
Git mockGit = Mockito.mock(Git.class);
PushCommand mockPushCommand = Mockito.mock(PushCommand.class);

// Stub the fluent method chain to return the mock command
Mockito.when(mockGit.push()).thenReturn(mockPushCommand);
Mockito.when(mockPushCommand.setCredentialsProvider(Mockito.any(UsernamePasswordCredentialsProvider.class)))
       .thenReturn(mockPushCommand);
// Make the call() method return a fake success result instead of throwing an exception
Mockito.when(mockPushCommand.call()).thenReturn(new PushResult());

// Use this mockGit instance in your test code instead of a real Git object
// Your code under test will interact with the mock, and no real push will occur

2. Use a Local Bare Repository as a "Mock Remote"

If you want to test the full push workflow without network calls, create a local bare repository to act as your fake remote. This mimics real push behavior but stays entirely on your local machine, making it great for integration-style tests.

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import java.io.File;
import java.nio.file.Files;

// Create a temporary local bare repository (acts as your mock remote)
File remoteRepoDir = Files.createTempDirectory("mock-remote-repo").toFile();
Git.init().setDirectory(remoteRepoDir).setBare(true).call();

// Configure your existing local repo to point to this mock remote
Git localGit = Git.open(yourLocalRepoDir);
localGit.remoteAdd()
        .setName("origin")
        .setUri(new URIish(remoteRepoDir.getAbsolutePath()))
        .call();

// Now execute the push command - it will push to the local bare repo, no network required
localGit.push()
        .setCredentialsProvider(new UsernamePasswordCredentialsProvider(PortalConstants.USERNAME, PortalConstants.PASSWORD))
        .call();

// Clean up temporary resources after the test
localGit.close();
// Add logic to delete remoteRepoDir if needed

3. Customize JGit's Transport to Skip Push Logic

For deeper control, you can override JGit's Transport class to skip the actual push operation. This is useful if you need to intercept push requests across your entire test suite.

import org.eclipse.jgit.transport.*;
import java.io.IOException;
import java.util.Collection;

// Custom Transport that fakes a successful push without doing any work
public class MockTransport extends Transport {
    protected MockTransport(Repository local, URIish uri) {
        super(local, uri);
    }

    @Override
    public void push(ProgressMonitor monitor, Collection<RemoteRefUpdate> refUpdates) throws IOException {
        // Mark all reference updates as successful
        for (RemoteRefUpdate update : refUpdates) {
            update.setStatus(RemoteRefUpdate.Status.OK);
        }
    }

    // Implement required abstract methods with no-op or fake behavior
    @Override
    public FetchConnection openFetch() throws IOException {
        return null;
    }

    @Override
    public PushConnection openPush() throws IOException {
        return null;
    }

    @Override
    public void close() {}
}

// Register the mock transport in your test setup
Transport.registerTransport("file", new TransportFactory() {
    @Override
    public Transport create(Repository local, URIish uri) {
        return new MockTransport(local, uri);
    }
});

// Now when you call git.push().call(), it will use your MockTransport and skip real push logic

Why You Were Seeing the Exception

The JGitInternalException you encountered is almost certainly because JGit was trying to connect to a real remote repository (like origin) that doesn't exist in your local test environment or isn't accessible. Any of the methods above will prevent that remote lookup and let you test safely locally.

内容的提问来源于stack exchange,提问作者Enosh Bansode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:53:47