簡體   English   中英

使用MOQ在同一接口中模擬方法

[英]Mocking a method in the same interface with MOQ

我有一個服務方法,我想測試。 該方法在同一個類中調用另一個方法。 這個方法已經過測試,所以我想模仿那個方法。

這是我的設置:

private readonly Mock<INewsLetterRepository> _mockNewsLetterRepository;
private readonly Mock<INewsLetterService> _mockNewsLetterService;
private readonly INewsLetterService _newsLetterService;

public NewsLetterServiceTest()
{
    _mockNewsLetterRepository = new Mock<INewsLetterRepository>();
    _mockNewsLetterService = new Mock<INewsLetterService> {CallBase = true};
    _newsLetterService = new NewsLetterService(_mockNewsLetterRepository.Object);
}

這是我正在使用的測試:

[TestMethod]
public void CreateNewsLetter_Should_Return_Empty_NewsLetter()
{
    var template = new Template
                   {
                       PlaceHolders = new List<TemplatePlaceholder>()
                   };
    var newsLetter = new NewsLetter {Template = template};
    const string content = "<html><body><!--BROWSER--></body></html>";
    _mockNewsLetterService.Setup(x => x.BuildNewsLetterHTML(It.IsAny<NewsLetter>())).Returns(content);

    var actual = _mockNewsLetterService.Object.CreateNewsLetter(newsLetter);
    Assert.AreEqual(content, actual);
}

現在的問題是我正在模擬的函數:BuildNewsLetterHTML返回null而不是它應該返回的內容。

這是我想要測試的函數的簡化版本:

public string CreateNewsLetter(NewsLetter newsLetter)
{
    var newsletterHTML = BuildNewsLetterHTML(newsLetter);
    return newsletterHTML;
}

所以問題是,至少在我看來,我模擬的函數不會返回它應該返回的內容字符串。 Assert.AreEqual上的測試失敗,因為實際為null。 你們中的任何人都知道為什么實際為空?

提前致謝。

似乎問題是你正在調用Mock<T>'s CreateNewsLetter方法,該方法尚未設置,並且似乎也是您正在測試的方法。 你不應該對你的假貨進行測試,它們應該替代生產代碼以幫助測試其他代碼。

我建議您在這種情況下使用提取和覆蓋模式 ,因為您希望在具有被測試方法的同一類的方法中導致偽實現。

Moq在某些情況下很棒,但我不認為在情況需要時使用小的可讀存根有什么問題。

public class YourTestClass
{
    [TestMethod]
    public void CreateNewsLetter_Should_Return_Empty_NewsLetter()
    {
        var template = new Template
        {
            PlaceHolders = new List<TemplatePlaceholder>()
        };
        var newsLetter = new NewsLetter { Template = template };

        const string content = "<html><body><!--BROWSER--></body></html>";

        INewsletterService service = new BuildNewsLetterStub(content);
        string actual = service.CreateNewsLetter(newsLetter);

        Assert.AreEqual(content, actual);
    }
}


public class BuildNewsLetterStub : NewsLetterService
{
    private string _letter;

    public BuildNewsLetterStub(string letter)
    {
        _letter = letter;
    }
    public override string BuildNewsLetterHTML(NewsLetter newsLetter)
    {
        return _letter;
    }
}

要覆蓋BuildNewsLetterHTML,必須將其標記為虛擬。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM