2012-04-10 6 views
0

Ich bin in Schreibgerät testen und habe ein nettes Repository-Muster/Moq, damit ich meine Funktionen testen, ohne "echte" Daten zu testen. So weit so gut .. aber ..Unit Testing Funktionen innerhalb Repository-Schnittstellen - ASP.NET MVC3 & Moq

In meiner Repository-Schnittstelle für „Beiträge“ IPostRepository Ich habe eine Funktion: Post getPostByID(int id); ich diese in die Lage sein will, testen von meiner Test-Klasse, kann aber nicht herausfinden, wie.

Bisher verwende ich dieses Muster für meine Tests:

[SetUp] 
public void Setup() 
{ 
    mock = new Mock<IPostRepository>(); 
} 

[Test] 
public void someTest() 
{ 
    populate(10); //This populates the mock with 10 fake entries 

    //do test here 
} 

In meiner Funktion „someTest“ Ich möchte in der Lage sein GetPostById die Funktion aufrufen/testen. Ich kann die Funktion mit mock.object.getpostbyid finden, aber das "Objekt" ist null.

Jede Hilfe würde geschätzt :)

iPostRepository:

public interface IPostRepository 
{ 
    IQueryable<Post> Posts {get;} 

    void SavePost(Post post); 
    Post getPostByID(int id); 
} 
+1

Wie erstellt 'populate (10)' die Daten? Das Erhalten einer NULL-Referenzausnahme für die 'object' -Eigenschaft des Mocks bedeutet normalerweise, dass der Mock nicht instanziiert wird, aber es sieht so aus, als ob Sie das in' [SetUp] 'tun. Es könnte sich lohnen, dafür zu sorgen, dass '[SetUp]' wie erwartet ausgeführt wird. – ataddeini

+0

Oh, ich glaube ich verstehe jetzt - ich lese "Objekt" ist null und ich dachte, du meintest die 'Objekt'-Eigenschaft des Mock. Ich denke, Marnix hat deine Antwort – ataddeini

+0

@ataddeini Ja, das Populat iteriert einfach und fügt dem Mock hinzu, um mich zu retten, die gleichen 10 Zeilen in jedem Testfall zu schreiben! – JustAnotherDeveloper

Antwort

1

Wenn Sie Ihr Mock-Objekt wollen ein Ergebnis (nicht null) zurück, müssen Sie es einrichten zu können:

mock.Setup(m => m.GetPostByID(5)).Returns(new Post()); 

Was Sie zurückkommen genau an Ihnen natürlich ist.

Update:

Wenn Sie die Methodenparameter verwenden müssen, können Sie auch ein Setup CallBack. Zum Beispiel:

Dies kann Ihren Setup-Code viel einfacher machen, da Sie den Mock nicht mit Daten vorbereiten müssen.

+0

Damm! Ich war so nah mit meiner Idee, ich habe das gemacht, wusste aber nichts von der Funktion returns()! Ich schaue mir das später an :) – JustAnotherDeveloper

1

Wenn Sie die reale Umsetzung der GetPostById testen wollen, tun dies über die reale Umsetzung der IPostRepository. Moq (und Mocks im Allgemeinen) sind nur für Situationen, in denen Sie nicht das echte Ding verwenden möchten.

Mit anderen Worten Prime Ihre Datenbank mit einigen Posts, neu in der realen Repository, rufen Sie GetPostById und machen Aussagen über das Ergebnis. Dies ist jedoch nicht unbedingt ein Komponententest, sondern ein Integrationstest, da er die Datenbank enthält.

2

Ich bin mir nicht sicher, welche Unit-Test-Framework Sie verwenden, aber ich benutze NUnit. Ich bin kein Testprofi, aber ich weiß genug, um mich zu starten und Ergebnisse zu erzielen.

Ich habe normalerweise eine Dienstschicht, und dies wird mein Beitrag Repository nennen:

public class PostService 
{ 
    private readonly IPostRepository postRepository; 

    public PostService(IPostRepository postRepository) 
    { 
      if (postRepository== null) 
      { 
       throw new ArgumentNullException("postRepository cannot be null.", "postRepository"); 
      } 

      this.postRepository = postRepository; 
    } 

    public Post GetPostById(int id) 
    { 
      return postRepository.GetPostById(id); 
    } 
} 

Ihre Unit-Tests könnte wie folgt aussehen:

[TestFixture] 
public class PostServiceTests 
{ 
    private PostService sut; 
    private Mock<IPostRepository> postRepositoryMock; 
    private Post post; 

    [SetUp] 
    public void Setup() 
    { 
      postRepositoryMock = new Mock<IPostRepository>(); 

      sut = new PostService(postRepositoryMock.Object); 

      post = new Post 
      { 
       Id = 5 
      }; 
    } 

    [Test] 
    public void GetPostById_should_call_repository_to_get_a_post_by_id() 
    { 
      int id = 5; 
      postRepositoryMock 
       .Setup(x => x.GetPostById(id)) 
       .Returns(post).Verifiable(); 

      // Act 
      Post result = sut.GetPostById(id); 

      // Assert 
      Assert.AreEqual(post, result); 
      postRepositoryMock.Verify(); 
    } 
} 

Ich hoffe, das hilft.

+0

Habe am Wochenende eine Auswahl dieser Ideen probiert und diese ist ganz nett! Ich werde es in Zukunft verwenden! – JustAnotherDeveloper

+0

Wenn es dann geholfen hat, gib es bitte eine Abstimmung :) –