2010-02-13 8 views
0

S'il vous plaît jeter un oeil à l'adresse suivante article about testing with mockstest unitaire avec des objets simulés

Donc, il est un exemple de test unitaire avec des objets fantaisie. Comme vous pouvez le voir, le test est écrit pour la méthode GetPersonByID. Dans l'interface IPersonServices, il existe une autre méthode: List<Person> GetPersons();

Quelqu'un peut-il me dire comment une méthode de test sur ce service devrait ressembler en utilisant des objets simulés? par exemple, dans le cas de GetPersons, qui a un type List.

Répondre

5

Vous feriez mieux de trouver un autre exemple de test unitaire avec Rhino.Mocks. L'exemple ici se moque de la classe réelle sous test, ce que vous ne feriez jamais.

Supposons que vous ayez un PersonRepository et un PersonService. Vous voulez tester unitaire le PersonService qui utilise le PersonRepository. Mise en œuvre de la personne omise.

public interface IPersonService 
{ 
     Person GetPerson(int id); 
     List<Person> GetPersons(); 
} 

public class PersonRepository 
{ 
     public virtual GetPerson(int id) 
     { 
      ... implementation 
     } 

     public virtual GetPersons() 
     { 
      ... implementation 
     } 
} 


public class PersonService : IPersonService 
{ 
    private PersonRepository Repository { get; set; } 

    public PersonService() : this(null) { } 

    public PersonService(PersonRepository repository) 
    { 
     this.Repository = repository ?? new PersonRepository(); 
    } 

    public Person GetPerson(int id) 
    { 
     return this.Repository.GetPerson(id); 
    } 

    public List<Person> GetPersons() 
    { 
     return this.Repository.GetPersons(); 
    } 
} 

Maintenant nous avons des tests unitaires pour nous assurer que le service appelle correctement le référentiel.

public void GetPersonTest() 
{ 
    var repository = MockRepository.GenerateMock<PersonRepository>(); 

    var expectedPerson = new Person(1, "Name"); 

    repository.Expect(r => r.GetPerson(1)).Return(expectedPerson); 

    var service = new PersonService(repository); 

    var actualPerson = service.GetPerson(1); 

    Assert.AreEqual(expectedPerson.ID, actualPerson.ID); 
    Assert.AreEqual(expectedPerson.Name, actualPerson.Name); 

    repository.VerifyAllExpectations(); 
} 

public void GetPersonsTest() 
{ 
    var repository = MockRepository.GenerateMock<PersonRepository>(); 

    var expectedPerson = new Person(1, "Name"); 

    var listOfPeople = new List<Person> { expectedPerson }; 

    repository.Expect(r => r.GetPersons()).Return(listOfPeople); 

    var service = new PersonService(repository); 

    var actualList = service.GetPersons(); 

    Assert.AreEqual(1, actualList.Count); 

    var actualPerson = actualList.First(); 

    Assert.AreEqual(expectedPerson.ID, actualPerson.ID); 
    Assert.AreEqual(expectedPerson.Name, actualPerson.Name); 

    repository.VerifyAllExpectations(); 
} 
+0

Vous n'avez pas besoin de mettre vos faux référentiels en mode relecture après avoir défini les attentes? –

+1

Ceci utilise la nouvelle syntaxe AAA (Arrange Act Assert) - il n'est pas nécessaire de les mettre explicitement en mode replay. – tvanfosson

+0

Nice. Je n'ai jamais vu cette syntaxe auparavant, et je n'ai pas remarqué que vous appeliez 'Expect()' directement sur l'objet fantaisie. Le wiki n'a pas encore beaucoup à dire sur la nouvelle syntaxe; La prochaine fois que j'écrirai des tests, je devrai essayer de contribuer. –

0

Comme tvanfosson said, ce n'est pas un exemple très utile. Voici un exemple du Rhino Mocks wiki.

 [Test] 
     public void SaveProjectAs_CanBeCanceled() 
     { 
      MockRepository mocks = new MockRepository(); 
      // projectView is the mock object 
      IProjectView projectView = mocks.StrictMock<IProjectView>(); 
      Project prj = new Project("Example Project"); 
      // presenter is the object under test 
      IProjectPresenter presenter = new ProjectPresenter(prj, projectView); 

      // set expectations on the mock object 
      Expect.Call(projectView.Title).Return(prj.Name); 
      Expect.Call(projectView.Ask(question, answer)).Return(null); 
      mocks.ReplayAll(); 

      // now execute the test 
      Assert.IsFalse(presenter.SaveProjectAs()); 
      mocks.VerifyAll(); 
     } 

Je ne pense pas qu'il y ait quelque chose de spécial à retourner un type de liste à partir d'un appel de méthode moqué. Juste mettre en place l'attente comme d'habitude. Dans l'exemple ci-dessus, si la méthode Ask() renvoyait une liste de chaînes, la méthode Return() après Expect.Call(...Ask...) prendrait une liste de chaînes. C'est la chose charmante de la combinaison d'enregistrement/relecture et génériques, vos attentes ont la sécurité de type intégré. Beaucoup plus agréable que les anciennes bibliothèques d'objets où vous avez tout défini avec la méthode noms dans les chaînes et toutes les valeurs de retour étaient juste des objets.

Pour plus d'explications sur cet exemple, ainsi que de nombreux autres, consultez le Rhino Mocks wiki.

+0

et comment configurer l'attente comme d'habitude? Peux-tu me donner un exemple? – qwerty