簡體   English   中英

具有依賴注入和MOQ的單元測試

[英]Unit Testing With Dependency Injection and MOQ

我只是在學習依賴注入和模擬是如何工作的,但是我想要一些關於我如何設置幾個測試的反饋。 我可以讓他們通過,但我不確定這是我需要的全部。

這是一個MVC應用程序,它使Web API調用返回數據。 對於此示例,我在填充下拉列表的Web API中運行查詢。

請給我任何和所有關於我在這里做對或錯的建議或我應該采取的不同做法。

依賴注入的設置文件 - Unity.WebAPI(NuGet包)

UnityConfig.cs

public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService, TestService>();

        container.RegisterType<IDropDownDataRepository, DropDownDataRepository>();

        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }
}

CONTROLLER

public class DropDownDataController : ApiController
{  
    private IDropDownDataRepository _dropDownDataRepository;

    //Dependency Injection (I'm using Unity.WebAPI)
    public DropDownDataController(IDropDownDataRepository dropDownDataRepository)
    {
        _dropDownDataRepository = dropDownDataRepository;
    }

    [HttpGet]
    public HttpResponseMessage DateList()
    {
        try
        {
            return _dropDownDataRepository.DateList();
        }
        catch
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
        }
    }
}

REPOSITORY

public class DropDownDataRepository : IDropDownDataRepository
{
    //Is this fine in here, or should it be injected somehow too?
    private MyDatabaseEntities db = new MyDatabaseEntities();  

    public HttpResponseMessage DateList()
    {
        var sourceQuery = (from p in db.MyProcedure()
                           select p).ToList();

        string result = JsonConvert.SerializeObject(sourceQuery);
        var response = new HttpResponseMessage();
        response.Content = new StringContent(result, System.Text.Encoding.Unicode, "application/json");

        return response;
    }
}

接口

public interface IDropDownDataRepository
{
    HttpResponseMessage DateList();
}  

單位測試

/// <summary>
/// Tests the DateList method is run
/// I pieced this kind of test together from examples online
/// I'm assuming this is good for a simple test
/// </summary>
[TestMethod]
public void DateListTest1()
{
    //Arrange
    var mockRepository = new Mock<IDropDownDataRepository>();
    mockRepository.Setup(x => x.DateList());           
    var controller = new DropDownDataController(mockRepository.Object);

    //Act
    controller.DateList();

    //Assert
    mockRepository.VerifyAll();
}



/// <summary>
/// Tests the DateList method returns correct status code.
/// This will run with success, but I'm not sure if that's just
/// because I'm telling it to return what I'm expecting.  
/// I welcome suggestions for improvement.
/// </summary>
[TestMethod]
public void DateListTest2()
{
    //Arrange
    var mockRepository = new Mock<IDropDownDataRepository>();
    mockRepository
        .Setup(x => x.DateList())
        //This will only succeed if I have the Returns property here,
        //but isn't that just bypassing the actual "test" of whether or
        //not this works?
        .Returns(new HttpResponseMessage(HttpStatusCode.OK));

    DropDownDataController controller = new DropDownDataController(mockRepository.Object);
    controller.Request = new HttpRequestMessage();
    controller.Configuration = new HttpConfiguration();

    //Act            
    var response = controller.DateList();

    //Assert
    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}

更新1

我在這里的一個主要問題是.Returns屬性實際上是做什么的。 在我的第二次單元測試中,我告訴它返回OK,然后檢查它是否返回OK。 我看不出它是如何測試任何東西的。

我在這里的一個主要問題是.Returns屬性實際上是做什么的。 在我的第二次單元測試中,我告訴它返回OK,然后檢查它是否返回OK。 我看不出它是如何測試任何東西的。

編碼:

mockRepository
        .Setup(x => x.DateList())
        //This will only succeed if I have the Returns property here,
        //but isn't that just bypassing the actual "test" of whether or
        //not this works?
        .Returns(new HttpResponseMessage(HttpStatusCode.OK));

說當mockRepository接收到對DateList()的調用時,它應該返回一個new HttpResponseMessage(HttpStatusCode.OK)

在里面

    [HttpGet]
    public HttpResponseMessage DateList()

當單元測試到達線路時

return _dropDownDataRepository.DateList();

模擬對象觸發並返回new HttpResponseMessage(HttpStatusCode.OK)

這個測試的更好的名稱將是DateListTest2而不是DateList_Returns_Status_Code_From_Repository因為這是你在測試中安排的。

說實話, controller.DateList()沒有太多的邏輯,所以這是你可以擁有的唯一的黃金路徑測試。

暫無
暫無

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

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