Question

J'essaie de trouver un moyen de simuler le résultat d'une méthode appelée depuis une autre méthode.

J'ai un " LoadData " méthode qui appelle un assistant distinct pour obtenir des données, puis les transformera (je souhaite tester le résultat transformé).

J'ai donc un code comme celui-ci:

public class MyClass(){
  public void LoadData(){
    SomeProperty = Helper.GetSomeData();
 }
 public object SomeProperty {get;set;}
}

Je souhaite obtenir un résultat connu de la méthode Helper.GetSomeData (). Puis-je utiliser un framework moqueur (j'ai une expérience assez limitée avec Rhino Mocks mais suis ouvert à tout) pour forcer un résultat attendu? Si oui, comment?

* Modifier - oui, comme prévu, je ne pouvais pas réaliser le piratage souhaité, je vais devoir trouver un meilleur moyen de configurer les données.

Était-ce utile?

La solution

Autant que je sache, vous devez créer une interface ou une classe abstraite de base pour l'objet Helper. Avec Rhino Mocks, vous pouvez ensuite renvoyer la valeur souhaitée.

Vous pouvez également ajouter une surcharge pour LoadData qui accepte en tant que paramètres les données que vous récupérez normalement à partir de l'objet Helper. Cela pourrait même être plus facile.

Autres conseils

Vous avez un problème là-bas. Je ne sais pas s'il s'agit d'un scénario simplifié de votre code, mais si la classe Helper est utilisée de cette manière, votre code n'est pas testable. Tout d’abord, la classe Helper est utilisée directement. Vous ne pouvez donc pas la remplacer par une maquette . Deuxièmement, vous appelez une méthode statique. Je ne connais pas le langage C #, mais en Java, vous ne pouvez pas remplacer les méthodes statiques .

Vous devrez procéder à quelques refactorisations pour pouvoir injecter un objet fictif avec une méthode GetSomeData () factice.

Dans cette version simplifiée de votre code, il est difficile de vous donner une réponse directe. Vous avez quelques options:

  • Créez une interface pour la classe Helper et donnez au client un moyen d'injecter l'implémentation Helper dans la classe MyClass. Mais si Helper est vraiment une classe d’utilité, cela n’a aucun sens.
  • Créez une méthode protégée dans myClass appelée getSomeData et appelez-la seulement Helper.LoadSomeData. Remplacez ensuite l'appel à Helper.LoadSomeData dans LoadData par for getSomeData. Vous pouvez maintenant simuler la méthode getSomeData pour renvoyer la valeur factice.

Ne vous contentez pas de créer une interface vers la classe Helper et insérez-la via une méthode. Cela peut exposer les détails de la mise en œuvre. Pourquoi un client doit-il fournir une implémentation d'une classe utilitaire pour appeler une opération simple? Cela augmentera la complexité des clients MyClass.

Je recommanderais de convertir ce que vous avez en quelque chose comme ceci:

public class MyClass()
{
    private IHelper _helper;

    public MyClass()
    {
        //Default constructor normal code would use.
        this._helper = new Helper();
    }

    public MyClass(IHelper helper)
    {
        if(helper == null)
        {
            throw new NullException(); //I forget the exact name but you get my drift ;)
        }
        this._helper = helper;
    }

    public void LoadData()
    {
        SomeProperty = this._helper.GetSomeData();
    }
    public object SomeProperty {get;set;}
}

Maintenant, votre classe prend en charge l’injection de dépendance. Cela vous permet d’injecter l’implémentation de la classe d’assistance et vous assure que votre classe ne dépend que de l’interface. Lorsque vous simulez ceci, sachez que vous créez simplement un simulacre utilisant l'interface IHelper et le transmettez au constructeur. Votre classe l'utilisera comme s'il s'agissait de la vraie classe Helper.

Maintenant, si vous êtes coincé dans l'utilisation de la classe Helper en tant que classe statique, je vous conseillerais d'utiliser un modèle proxy / adaptateur et d'envelopper la classe statique avec une autre classe prenant en charge l'interface IHelper (que vous devrez également créer). ).

Si, à un moment donné, vous souhaitez aller plus loin, vous pouvez supprimer complètement l'implémentation Helper par défaut de la classe révisée et utiliser des conteneurs IoC (Inversion of Control). Si ceci est nouveau pour vous, je vous conseillerais de vous concentrer sur les raisons pour lesquelles tous ces tracas supplémentaires valent la peine (c’est à mon humble avis).

Vos tests unitaires ressembleront à quelque chose comme ceci: pseudo-code:

public Amazing_Mocking_Test()
{
    //Mock object setup
    MockObject mockery = new MockObject();
    IHelper myMock = (IHelper)mockery.createMockObject<IHelper>();
    mockery.On(myMock).Expect("GetSomeData").WithNoArguments().Return(Anything);

    //The actual test
    MyClass testClass = new MyClass(myMock);
    testClass.LoadData();

    //Ensure the mock had all of it's expectations met.
    mockery.VerifyExpectations();
}

N'hésitez pas à commenter si vous avez des questions. (Au fait, je ne sais pas si tout ce code fonctionne, je viens de le taper dans mon navigateur, je vais surtout illustrer les concepts.)

Vous voudrez peut-être examiner Typemock Isolator, qui peut "simuler". méthode appelle sans vous obliger à refactoriser votre code. Je suis un développeur dans cette entreprise, mais la solution est viable si vous souhaitez choisir de ne pas modifier votre conception (ou obligée de ne pas la modifier pour en vérifier la testabilité). c'est à www.Typemock.com

Roy blog: ISerializable.com

Oui, un cadre moqueur est exactement ce que vous recherchez. Vous pouvez enregistrer / organiser la façon dont vous souhaitez que certaines classes simulées / tronquées soient renvoyées.

Rhino Mocks, Typemock et Moq sont de bonnes options pour cela.

Le message de Steven Walther sur l'utilisation de Rhino Mocks m'a beaucoup aidé lorsque j'ai commencé à jouer avec Rhino Mocks.

Je voudrais essayer quelque chose comme ça:

public class MyClass(){
  public void LoadData(IHelper helper){
    SomeProperty = helper.GetSomeData();
 }

De cette façon, vous pouvez simuler la classe d'assistance en utilisant, par exemple, MOQ.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top