簡體   English   中英

使用 xUnit/Moq 進行控制器 API 測試 - 控制器為空

[英]Controller API Testing with xUnit/Moq - Controller is null

我是單元測試的新手,所以我的問題可能出在我的代碼而不是 Moq 框架上,但這里是。

我將 .Net Core 與 xUnit 和 Moq 框架一起使用,我或多或少地遵循他們文檔中的說明 我正在嘗試測試路由api/user以獲取所有用戶,問題在於斷言響應是包含<IEnumerable<User>>ObjectResult 無論我嘗試什么, result.Value始終為空。 第一個斷言通過得很好。

我設置了一個控制台項目來調試它,並發現了一些有趣的東西。 Visual Studio 中測試方法中控制器的值為空。 在 VS Code 中,調試器中的值顯示Unknown Error: 0x00000...

下面是測試:

public class UserControllerTests {

    [Fact]
    public void GetAll_ReturnsObjectResult_WithAListOfUsers() {
        // Arrange
        var mockService = new Mock<IUserService>();
        var mockRequest = new Mock<IServiceRequest>();
        mockService.Setup(svc => svc.GetUsers(mockRequest.Object))
            .Returns(new ServiceRequest(new List<User> { new User() }));
        var controller = new UserController(mockService.Object);

        // Act
        var result = controller.GetAll();

        // Assert
        Assert.IsType<ObjectResult>(result);
        Assert.IsAssignableFrom<IEnumerable<User>>(((ObjectResult)result).Value);
    }

}

這是控制器:

public class UserController : Controller {

    private IUserService service;

    public UserController(IUserService service) {
        this.service = service;
    }

    [HttpGet]
    public IActionResult GetAll() {
        var req = new ServiceRequest();
        service.GetUsers(req);

        if(req.Errors != null) return new BadRequestObjectResult(req.Errors);
        return new ObjectResult(req.EntityCollection);
    }

}

和服務層:

public interface IUserService {
    IServiceRequest GetUsers(IServiceRequest req);
}    
public class UserService : IUserService {       
    private IUserRepository repo;       
    public IServiceRequest GetUsers(IServiceRequest req) {
        IEnumerable<User> users = null;         
        try {
            users = repo.GetAll();
        }
        catch(MySqlException ex) {
            req.AddError(new Error { Code = (int)ex.Number, Message = ex.Message });
        }
        finally {
            req.EntityCollection = users;
        }
        return req;
    }
}

public interface IServiceRequest {
    IEnumerable<Object> EntityCollection { get; set; }
    List<Error> Errors { get; }
    void AddError(Error error);
}
public class ServiceRequest : IServiceRequest {
    public IEnumerable<Object> EntityCollection { get; set; }
    public virtual List<Error> Errors { get; private set; }

    public ServiceRequest () { }

    public void AddError(Error error) {
        if(this.Errors == null) this.Errors = new List<Error>();
        this.Errors.Add(error);
    }       
}

就像我說的,這可能是我做錯了,我在mockService.Setup()思考,但我不確定在哪里。 請幫忙?

從使用的service.GetUsers(req)它看起來像service是假設填充服務請求,但在你的安裝你有它返回一個服務請求。 根據您的代碼也未使用的結果。

您需要一個Callback來填充提供給服務的任何參數,以便在調用時模擬/復制。 由於參數是在方法內部創建的,您將使用 Moq 的It.IsAny<>來允許模擬接受傳遞的任何參數。

var mockService = new Mock<IUserService>();
mockService.Setup(svc => svc.GetUsers(It.IsAny<IServiceRequest>()))
    .Callback((IServiceRequest arg) => {
        arg.EntityCollection = new List<User> { new User() };
    });

這應該允許被測方法流過它的調用並允許您斷言結果。

暫無
暫無

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

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