Comment puis-je accès privé aux membres de la classe en Java?
J'ai des données du modèle de classes qui contiennent des champs privés, qui sont censées être en lecture seule (par l'intermédiaire d'une fonction get). Ces champs sont définis par mon fournisseur de persistance JPA (eclipselink) pendant le fonctionnement normal, à l'aide du contenu de la base de données. Pour les tests unitaires, je veux mettre à de fausses valeurs à partir d'une maquette de la couche de persistance. Comment puis-je le faire? Comment eclipselink définir ces valeurs, de toute façon?
Exemple simplifié:
@Entity
class MyEntity
{
@Id
private Integer _ix;
public Integer ixGet()
{
return this._ix;
}
}
Vous devez vous connecter pour publier un commentaire.
Pouvez-vous juste de se Moquer de l'Entité elle-même, la fourniture de votre propre implemenations les accesseurs?
Vous pouvez créer un anonyme extension dans votre maquette couche de persistance:
Vous devez utiliser l'API Reflection. Utilisation De La Classe.getField() pour obtenir le champ, puis d'appeler setAccessable(vrai) sur le terrain de sorte que vous pouvez écrire, même si c'est privé, et enfin, vous pouvez appeler set() pour écrire une nouvelle valeur.
Par exemple:
Vous souhaitez définir le champ 'i' à 3, même si c'est privé:
Il y a un certain nombre d'exceptions que vous aurez besoin pour gérer.
Vous pouvez utiliser une bibliothèque de test comme Mockito pour accéder à des objets internes de l'état en lecture et en écriture. Par exemple avec Mockito utilisation:
Vous pouvez utiliser un moqueur cadre comme powermock à faire de l'encapsulation. Dans powermock que vous souhaitez utiliser
Whitebox.setInternalState(..)
pour définir un membre privé.Une méthode moins invasive serait de se moquer de la méthode de lecture. Si cela est faisable dépendra de ce que l'autre dépend de l'état interne, mais si c'est assez, c'est la solution de nettoyage.
Quelques méthodes que j'ai utilisé dans le passé:
Une autre option, si vous avez vraiment la haine pour rendre les choses publiques, est de créer une sous-classe pour les tests, et de fournir un accès public là.
Vous avez un peu d'options:
Pour un tas de techniques utiles, ont un coup d'oeil à Michael Plume du livre, Travailler Efficacement Avec Le Code Existant
Vous pouvez ajouter constructeur avec paramètre en lecture seule variable. N'oubliez pas d'ajouter une valeur par défaut (zéro en paramètre au constructeur.
Le constructeur est une meilleure façon, je pense. Si cette entité doit être vraiment en lecture seule (pas le droit de créer de nouvelles instances dans le code de production à tous), vous pouvez faire de constructeur avec le paquet de l'accès et de l'utiliser uniquement dans les tests. Et il ya une possibilité que, même si vous faites votre constructeur par défaut ou privé avec accès au package, votre persistance fournisseur de toujours être en mesure de travailler avec une telle entité, mais pas sûr de bien - vérifier avec eclipselink docs.