如何在外部DLL中测试和调用我的api

时间:2017-09-07 14:42:49

标签: c# unit-testing asp.net-core-webapi asp.net-core-mvc-2.0

第一次使用ASP.NET Core 2.0。

我有一个Web项目,它引用了我创建的DLL。

在这个DLL中是一个简单的方法......

namespace InformedWorkerApi
{
    [Route("api/[controller]")]
    public class RegistrationController: Controller
    {
        private readonly IAccountRepository _accountRepository;
        public RegistrationController(IAccountRepository accountRepository)
        {
            _accountRepository = accountRepository;
        }

        [HttpPost()]
        [Route("SignOn")]
        public async Task<InformedWorkerModels.Account> SignOn([FromBody]SignOnRequest model)
        {
            return await _accountRepository.SignOn(model.EmailAddress, model.Password);
        }
    }
}

我还创建了一个引用我的DLL的测试项目......

    [TestMethod]
    public async Task SignOn()
    {

        var webHostBuilder = new WebHostBuilder()
            .UseStartup<Startup>();

        using (var host = new TestServer(webHostBuilder))
        {
            using (var client = host.CreateClient())
            {
                var requestData = new SignOnRequest { EmailAddress = "emailAddress", Password= "password" };
                var content = new StringContent(JsonConvert.SerializeObject(requestData), Encoding.UTF8, "application/json");
                var response = await client.PostAsync("api/Registration/SignOn", content);
                //do some asserts here
            }
        }
    }

我收不到错误状态代码404。

我在这里弄错了什么?

1 个答案:

答案 0 :(得分:1)

您有电子邮件和密码作为路线的一部分,但将其作为内容发送到正文中。与行动的路线模板不匹配,因此404 Not Found。

创建一个模型来保存数据

public class SignOnRequest {
    [Required]
    public string emailAddress { get; set; }
    [Required]
    public string password { get; set; }
}

同样对于核心,您必须使用参数属性指定框架应该查找参数。

[Route("api/[controller]")]
public class RegistrationController : Controller{

    [HttpPost()]
    [Route("SignOn")] // Matches POST api/Registration/SignOn
    public async Task<IActionResult> SignOn([FromBody]SignOnRequest model) {
        if(ModelState.IsValid) {                
            var response = await _accountRepository.SignOn(model.emailAddress, model.password);
            return Ok(response);
        }
        return BadRequest();
    }
}

现在应该与集成测试中的请求相匹配

var requestData = new { emailAddress = "emailAddress", password = "password" };
var content = new StringContent(JsonConvert.SerializeObject(requestData), Encoding.UTF8, "application/json");
var response = await client.PostAsync("api/Registration/SignOn", content);

正如您还提到控制器在另一个程序集中,您需要确保控制器已在ServiceCollection内的Startup注册,以便框架知道如何解析控制器。更新ConfigureServices以包含

services.AddMvc()
  .AddApplicationPart(typeof(RegistrationController).GetTypeInfo().Assembly)
  .AddControllersAsServices();

从以下答案ASP.NET Core MVC controllers in separate assembly

中引用