Testando membros privados com Private Imports

Escrever testes unitários pode ser uma tarefa desafiadora quando o objeto a ser testado possui propriedades ou métodos privados. Neste cenário o uso de mocks não é aplicável e uma solução recorrente é escrever propriedades ou métodos adicionais para va…


This content originally appeared on DEV Community and was authored by Patrick Lorran

Escrever testes unitários pode ser uma tarefa desafiadora quando o objeto a ser testado possui propriedades ou métodos privados. Neste cenário o uso de mocks não é aplicável e uma solução recorrente é escrever propriedades ou métodos adicionais para validar os membros privados, poluindo o objeto. Neste artigo trago uma solução alternativa que envolve o uso de flags de compilação e atributos privados da linguagem para acessar os membros privados somente no ambiente de teste.

Configuração Inicial

O primeiro passo é adicionar a flag -enable-private-imports ao seu pacote ou aplicação. Essa flag instrui o compilador a expor membros internos e privados desde que sejam explicitados no código-fonte (falaremos disso mais adiante). No seu arquivo de pacote adicione o parâmetro swiftSettings à descrição do target e utilize o método unsafeFlags(_:_:) para inserir a flag mencionada.

.target(
  name: "MyAwesomeLibrary",
  dependencies: [
    ...
  ],
  swiftSettings: [
    .unsafeFlags(["-enable-private-imports"], .when(configuration: .debug))
  ])

Neste exemplo restringimos a flag à configuração debug pois não queremos que nosso código de produção exponha os membros privados. Basta utilizar um objeto do tipo BuildSettingCondition para especificar as condições sob as quais as flags de compilação serão aplicadas.

Caso queira expor os membros privados da sua aplicação, adicione a flag na opção Other Swift Flags em Swift Compiler - Custom Flags na aba Build Settings do projeto.

Implementação

Suponhamos que nosso pacote tenha o seguinte código no arquivo Operations.swift:

public struct Operations {

  private var count: Int = 0

  public func sum(_ x: Int, _ y: Int) -> Int {
    count += 1
    return x + y
  }
}

A variável count registra o número de operações de soma realizadas — ou seja, a quantidade de vezes que o método sum(_:_:) foi invocado. Vamos, agora, escrever testes unitários para nosso objeto.

import XCTest

@testable import MyAwesomeLibrary

final class OperationsTests: XCTestCase {

  private var operations: Operations!

  override func setup() {
    super.setup()

    operations = .init()
  }

  func testSum() {
    let result = operations.sum(2, 3)
    XCTAssertEqual(result, 5)
  }
}

O método testSum() apenas confere se a operação de soma do nosso objeto está correta. Para podermos testar se a variável count está sendo incrementada a cada chamada temos que expô-la para nossa classe de teste. Para isso adicionaremos o atributo privado @_private(sourceFile:) à nossa diretiva de importação passando como argumento o nome do arquivo que contém o código-fonte dos membros privados a serem expostos.

import XCTest

@_private(sourceFile: "Operations.swift")
@testable import MyAwesomeLibrary

final class OperationsTests: XCTestCase {

  private var operations: Operations!

  override func setup() {
    super.setup()

    operations = .init()
  }

  func testSum() {
    let result = operations.sum(2, 3)

    XCTAssertEqual(result, 5)
  }

  func testCount() {
    let _ = operations.sum(2, 3)
    let _ = operations.sum(4, 5)

    XCTAssertEqual(operations.count, 2)
  }
}

O método testCount() verifica se após duas chamadas de sum(_:_:) a variável count é incrementada duas vezes. A assertiva acessa a propriedade count do objeto operations sem causar um erro de compilação graças ao atributo @_private(sourceFile: "Operations.swift") que inserimos ao importar o módulo.

Dessa forma, sempre que precisar testar membros privados de determinado objeto, importe o módulo com o atributo @_private(sourceFile:) antes e passe como argumento o nome do arquivo que contém esse objeto.

Conclusão

A exposição de membros privados pode facilitar muito a escrita dos testes unitários por eliminar a necessidade de membros auxiliares que de nada servem a não ser observar outros membros. Apenas se atente para que a flag não seja aplicada à compilação de release a fim de evitar a exposição desnecessária de membros privados.


This content originally appeared on DEV Community and was authored by Patrick Lorran


Print Share Comment Cite Upload Translate Updates
APA

Patrick Lorran | Sciencx (2023-02-26T22:38:13+00:00) Testando membros privados com Private Imports. Retrieved from https://www.scien.cx/2023/02/26/testando-membros-privados-com-private-imports/

MLA
" » Testando membros privados com Private Imports." Patrick Lorran | Sciencx - Sunday February 26, 2023, https://www.scien.cx/2023/02/26/testando-membros-privados-com-private-imports/
HARVARD
Patrick Lorran | Sciencx Sunday February 26, 2023 » Testando membros privados com Private Imports., viewed ,<https://www.scien.cx/2023/02/26/testando-membros-privados-com-private-imports/>
VANCOUVER
Patrick Lorran | Sciencx - » Testando membros privados com Private Imports. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2023/02/26/testando-membros-privados-com-private-imports/
CHICAGO
" » Testando membros privados com Private Imports." Patrick Lorran | Sciencx - Accessed . https://www.scien.cx/2023/02/26/testando-membros-privados-com-private-imports/
IEEE
" » Testando membros privados com Private Imports." Patrick Lorran | Sciencx [Online]. Available: https://www.scien.cx/2023/02/26/testando-membros-privados-com-private-imports/. [Accessed: ]
rf:citation
» Testando membros privados com Private Imports | Patrick Lorran | Sciencx | https://www.scien.cx/2023/02/26/testando-membros-privados-com-private-imports/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.