2010-05-26 20 views
2

Quelle est la principale différence entre ces deux façons de donner à une méthode une fausse implémentation? J'utilisais la deuxième manière très bien dans un test mais dans un autre test, le comportement ne peut pas être atteint à moins que je ne parte de la première façon.Différence dans les techniques de définition de la valeur de retour d'une méthode stubbed avec Rhino Mocks

si (la première),

using (test.Record()) //test is MockRepository instance 
{ 
service.GetUser("dummyName"); 
LastCall.Return(new LoginUser()); 
} 

vs (la seconde).

service.Stub(r => r.GetUser("dummyName")).Return(new LoginUser()); 

Modifier

Le problème est que la deuxième technique renvoie null dans le test, quand je pense à retourner une nouvelle LoginUser. La première technique se comporte comme prévu en retournant un nouveau LoginUser. Tous les autres codes de test utilisés dans les deux cas sont identiques.

[TestFixture] 
public class AuthorizationTest 
{ 
    private MockRepository test; 
    private IMembershipService service; 

    [SetUp] 
    public void SetUp() 
    { 
     test = new MockRepository(); 
     service = test.Stub<IMembershipService>(); 

     using (test.Record()) 
     { 
      service.GetUser("dummyName"); 
      LastCall.Return(new LoginUser()); 
     } 

     //service.Stub(r => r.GetUser("dummyName")).Return(new LoginUser()); 
    } 

    [Test] 
    public void GetCurrentUser_UserIsAuthenticated_ReturnsCurrentUser() 
    { 
     var authStub = new AuthorizationStub_SetCurrentUserAuthenticated(service, true); 

     LoginUser u = authStub.GetCurrentUser(); 
     Assert.That(u != null); 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     service = null; 
     test = null; 
    } 
} 

Pourrait-il être quelque chose à voir avec la surcharge de l'interface peut-être?

public interface IMembershipService 
{ 
    bool ChangePassword(string username, string oldPassword, string newPassword); 
    LoginUser GetUser(string username); 
    LoginUser GetUser(object providerUserKey); 
    string ResetPassword(string username); 
    bool ValidateUser(string username, string password); 
} 

La ligne origine du problème dans la méthode à l'essai est:

LoginUser currentUser = _repository.GetUser(identity.Name); 

En mode débogage, identity.Name est jamais nul et est toujours « dummyName »

Répondre

3

la deuxième méthode est le nouveau AAA syntax, et est la méthode préférée. Vous pourriez peut-être développer les problèmes que vous avez rencontrés en utilisant la syntaxe AAA, et vous pourriez peut-être obtenir de l'aide pour régler ce problème.

EDIT:

Etes-vous sûr que la méthode est appelée avec ce paramètre? Que se passe-t-il si vous utilisez

service.Stub(r => r.GetUser(Arg<String>.Is.Anything)).Return(new LoginUser()); 

Avez-vous un retour?

Et si vous définissiez une attente plutôt que de simplement la talonner et que vous vérifiiez les attentes, cela pourrait-il vous donner plus d'informations?

service.Expect(r => r.GetUser(Arg<String>.Is.Anything)).Return(new LoginUser()); 
service.VerifyAllExpectations(); 

EDIT2:

ok je l'ai fait un peu d'essais et il semble que ce soit la façon dont vous créez votre objet stub. Je suppose que la façon dont vous utilisez est le style ancien et que vous devez utiliser pour le nouveau style:

service = MockRepository.GenerateStub<IMembershipService>(); 

Quand j'ai changé à ce que je peux exécuter les tests et les amener à passer. Je ne suis pas certain de la différence exacte entre l'utilisation de la méthode statique pour générer le talon et l'utilisation de l'instance de test MockRepository. Peut-être que quelqu'un d'autre peut en expliquer les tenants et aboutissants.

Quoi qu'il en soit pour être complet est ici le code que je courais, qui a travaillé:

[TestFixture] 
public class AuthorizationTest 
    { 
    private IMembershipService service; 

    [SetUp] 
    public void SetUp() 
     { 
     service = MockRepository.GenerateStub<IMembershipService>(); 
     service.Stub(r => r.GetUser("dummyName")).Return(new LoginUser()); 
     } 

    [Test] 
    public void GetCurrentUser_UserIsAuthenticated_ReturnsCurrentUser() 
     { 
     var authStub = new AuthorizationStub_SetCurrentUserAuthenticated(service, true); 

     LoginUser u = authStub.GetCurrentUser(); 
     Assert.That(u != null); 
     } 

    [TearDown] 
    public void TearDown() 
     { 
     service = null; 
     } 
    } 

public class AuthorizationStub_SetCurrentUserAuthenticated 
    { 
    private readonly IMembershipService m_service; 
    private readonly bool m_b; 

    public AuthorizationStub_SetCurrentUserAuthenticated (IMembershipService service, bool b) 
     { 
     m_service = service; 
     m_b = b; 
     } 

    public LoginUser GetCurrentUser() 
     { 
     return m_service.GetUser ("dummyName"); 
     } 
    } 

public interface IMembershipService 
    { 
    bool ChangePassword(string username, string oldPassword, string newPassword); 
    LoginUser GetUser(string username); 
    LoginUser GetUser(object providerUserKey); 
    string ResetPassword(string username); 
    bool ValidateUser(string username, string password); 
    } 

public class LoginUser 
    { 
    } 
+0

Ok, merci. J'ai ajouté quelques informations supplémentaires. – CRice

+0

mis à jour ma réponse avec quelques autres idées ... –

+0

Merci pour les exemples. C'est bizarre, le test échoue encore à moins qu'il n'y ait la présence du talon avec record et lastcall. Lorsque ce talon est là ET j'inclue également votre service.Expect et service.VerifyAllExpectations il passe. Si j'échange le talon d'enregistrement et lastcall avec votre exemple de talon, il échoue. – CRice