首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用于单元测试api控制器的示例代码

用于单元测试api控制器的示例代码
EN

Stack Overflow用户
提问于 2012-04-06 18:31:26
回答 3查看 13.9K关注 0票数 18

是否有示例代码显示了对继承自api控制器的控制器进行单元测试?我正在尝试对POST进行单元测试,但它失败了。我想我需要设置HttpControllerContext以进行测试,但不知道如何设置,谢谢

EN

回答 3

Stack Overflow用户

发布于 2012-06-07 22:56:00

这段代码应该演示post测试的基础知识。假设您已经将存储库注入到控制器中。我使用的是MVC4RC,而不是测试版,如果你使用的是测试版的Request.CreateResponse(...有点不同所以给我一个呼喊。

给定的控制器代码有点像下面这样:

代码语言:javascript
复制
public class FooController : ApiController
{
    private IRepository<Foo> _fooRepository;

    public FooController(IRepository<Foo> fooRepository)
    {
        _fooRepository = fooRepository;
    }

    public HttpResponseMessage Post(Foo value)
    {
        HttpResponseMessage response;

        Foo returnValue = _fooRepository.Save(value);
        response = Request.CreateResponse<Foo>(HttpStatusCode.Created, returnValue, this.Configuration);
        response.Headers.Location = "http://server.com/foos/1";

        return response;
    }
}

单元测试看起来有点像这样(NUnit和RhinoMock)

代码语言:javascript
复制
        Foo dto = new Foo() { 
            Id = -1,
            Name = "Hiya" 
        };

        IRepository<Foo> fooRepository = MockRepository.GenerateMock<IRepository<Foo>>();
        fooRepository.Stub(x => x.Save(dto)).Return(new Foo() { Id = 1, Name = "Hiya" });

        FooController controller = new FooController(fooRepository);

        controller.Request = new HttpRequestMessage(HttpMethod.Post, "http://server.com/foos");
        //The line below was needed in WebApi RC as null config caused an issue after upgrade from Beta
        controller.Configuration = new System.Web.Http.HttpConfiguration(new System.Web.Http.HttpRouteCollection());

        var result = controller.Post(dto);

        Assert.AreEqual(HttpStatusCode.Created, result.StatusCode, "Expecting a 201 Message");

        var resultFoo = result.Content.ReadAsAsync<Foo>().Result;
        Assert.IsNotNull(resultFoo, "Response was empty!");
        Assert.AreEqual(1, resultFoo.Id, "Foo id should be set");
票数 10
EN

Stack Overflow用户

发布于 2014-03-05 22:25:55

使用AutoFixture时,我通常会这样做:

代码语言:javascript
复制
[Theory, AutoCatalogData]
public void PostToCollectionReturnsCorrectResponse(
    CategoriesController sut,
    CategoryRendition categoryRendition)
{
    HttpResponseMessage response = sut.Post(categoryRendition);

    Assert.Equal(HttpStatusCode.Created, response.StatusCode);
}

有关此方法的更多详细信息,请参阅this other SO answer

票数 1
EN

Stack Overflow用户

发布于 2014-03-05 20:06:53

我已经创建了一个通用的解决方案,用于调用一些操作并以Dictionary的形式获取HttpResponseMessage,这非常便于使用。

首先是对dictionary的一些扩展

代码语言:javascript
复制
public static class DictionaryExtensions
{
    public static void AddRange<T, S>(this Dictionary<T, S> source,
                                      Dictionary<T, S> collection) 
    {
        if (collection == null)
        {
            throw new NullReferenceException("Collection is null");
        }

        foreach (var item in collection)
        {
            source.Add(item.Key, item.Value);
        }
    }
}

现在请求创建part:

代码语言:javascript
复制
public class RequestCreator
{
    protected static void FirstPart(ApiController controller,
                                    HttpMethod method,String actionUrl)
    {
        // Creating basic request message with message type and requesting 
        // url example : 'http://www.someHostName/UrlPath/'
        controller.Request = new HttpRequestMessage(method, actionUrl);

        // Adding configuration for request
        controller.Request.Properties.
          Add(HttpPropertyKeys.HttpConfigurationKey,new HttpConfiguration());                                         
    }

    protected static Dictionary<String, Object> SecondPart
                                                 (HttpResponseMessage response)
    {
        // Adding basic response content to dictionary
        var resultCollection = new Dictionary<String, Object>
        {
            {"StatusCode",response.StatusCode},
            {"Headers",response.Headers},
            {"Version",response.Version},
            {"RequestMessage",response.RequestMessage},
            {"ReasonPhrase",response.ReasonPhrase},
            {"IsSuccessStatusCode",response.IsSuccessStatusCode}
        };

        var responseContent = response.Content;
        // If response has content then parsing it and 
        // getting content properties
        if (null != responseContent)
        {
            var resultMessageString = response.Content.
                                               ReadAsStringAsync().Result;
            resultCollection.AddRange((new JavaScriptSerializer()).
                                       DeserializeObject(resultMessageString) 
                                               as Dictionary<String, Object>);
        }


        return resultCollection;
    }       
}

最后响应消息到字典转换器class

代码语言:javascript
复制
public class HttpResponseModelGetter : RequestCreator
{
    public Dictionary<String, Object>
                 GetActionResponse(ApiController controller,HttpMethod method,
                          String actionUrl,Func<HttpResponseMessage> callBack)
    {
        FirstPart(controller, method, actionUrl);
        var response = callBack();
        return SecondPart(response);
    }
}

public class HttpResponseModelGetter<T> : RequestCreator
{
    public Dictionary<String, Object> 
             GetActionResponse(ApiController controller,HttpMethod method,
                String actionUrl,Func<T,HttpResponseMessage> callBack,T param) 
    {
        FirstPart(controller, method, actionUrl);
        var response = callBack(param);
        return SecondPart(response);
    }
}

public class HttpResponseModelGetter<T1,T2> : RequestCreator
{
    public Dictionary<String, Object> 
        GetActionResponse(ApiController controller,HttpMethod method, 
             String actionUrl,Func<T1,T2,HttpResponseMessage> callBack,
             T1 param1,T2 param2)


    {
        FirstPart(controller, method, actionUrl);
        var response = callBack(param1,param2);
        return SecondPart(response);
    }
} 
//and so on...

和用法:

代码语言:javascript
复制
var responseGetter = new HttpResponseModelGetter();
var result = responseGetter.GetActionResponse(controller,HttpMethod.Get,
                    "http://localhost/Project/api/MyControllerApi/SomeApiMethod",
                                              controller.SomeApiMethod);

Boolean isComplete = Boolean.Parse(result["isComplete"].ToString());
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10042290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档