Мой фиктивный тест для клиента Github содержит грязные заглушки, и мне кажется, что я тестирую детали реализации - PullRequest
0 голосов
/ 07 января 2020

Я написал класс 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?

...