Я написал класс GithubClient
, который в основном является оберткой для библиотеки Ruby Octokit
.
Он содержит один метод publi c помимо конструктора, который называется push
, который в основном создает коммит в удаленном режиме.
Я сделал параметры переменных экземпляра для конструктора и затем предоставил значения по умолчанию, поэтому я могу ввести макет.
Он имеет закрытые методы для создания коммитов и pu sh фиксирует деревья, которые используют Octokit
, и я думаю, что я использую это стандартным способом. Я скопировал большую часть кода в режиме онлайн.
class GithubClient
def initialize(
octokit_client=Octokit::Client.new(:access_token => ENV['GITHUB_WRITE_TOKEN']),
repo_name='main',
ref_name='heads/master'
)
@client = octokit_client
@repo = repo_name
@ref = ref_name
end
def push(underwriter, files)
sha_new_commit = create_new_commit(underwriter, files)
push_commit_tree(sha_new_commit)
end
private
def create_new_commit(underwriter, files)
sha_latest_commit = @client.ref(@repo, @ref).object.sha
sha_base_tree = @client.commit(@repo, sha_latest_commit).commit.tree.sha
new_commit_tree = files.map do |file|
blob_sha = @client.create_blob(@repo, file)
{
:path => file.git_path_name,
:mode => "100644",
:type => "blob",
:sha => blob_sha,
}
end
sha_new_tree = @client.create_tree(@repo, new_commit_tree, {:base_tree => sha_base_tree }).sha
commit_message = "commit - #{files.first.name}"
sha_new_commit = @client.create_commit(@repo, commit_message, sha_new_tree, sha_latest_commit).sha
end
def push_commit_tree(sha_new_commit)
@client.update_ref(@repo, @ref, sha_new_commit)
end
end
Затем я написал для этого фиктивный тест, как показано ниже
def test_octokit
octokit_client = mock()
octokit_client.stubs(:ref).returns(stub(:object => stub(:sha => "sha1")))
octokit_client.stubs(:commit).returns(stub(:commit => stub(:tree => stub(:sha => "sha2"))))
octokit_client.stubs(:create_blob).returns("blob sha")
octokit_client.stubs(:create_commit).returns(stub(:sha => "new commit sha"))
octokit_client.expects(:create_tree).with("repo_name", [{:path => "", :mode => "100644", :type => "blob", :sha => "blob sha"}], {:base_tree => "sha2"}).once.returns(stub(:sha => "sha3"))
octokit_client.expects(:update_ref).with("repo_name", "ref_name", "new commit sha")
github_client = Undertaker::Mapper::GithubClient.new(octokit_client, 'repo_name', 'ref_name')
github_client.push('', [FakeFile.new])
end
Он действительно проверяет, что .create_tree
и .create_commit
вызывается один раз с ожидаемыми параметрами.
Однако, поскольку реализация GithubClient имеет так много вложенных вызовов (например, .commit.tree.sha
), мне пришлось заглушить все эти вызовы. Это очень грязно и беспокоит меня.
Кроме того, хотя в моем тесте я звоню только push
, моя заглушка предполагает знание вызовов, сделанных в частных методах, и я чувствую, что проверяю детали реализации.
Я правильно делаю? Кроме того, что нужно проверить в классе, подобном моему GithubClient
?