IHttpActionResult ফেরত দেওয়ার পরে আমি কীভাবে ওয়েব অ্যাপি অ্যাকশন পদ্ধতির পরীক্ষা করব?


135

আসুন ধরে নেওয়া যাক এটি আমার ক্রিয়া পদ্ধতি

public IHttpActionResult Get(int id)
{
    var status = GetSomething(id);
    if (status)
    {
        return Ok();
    }
    else
    {
        return NotFound();
    }
}

পরীক্ষা হবে

var httpActionResult = controller.Get(1);

এর পরে আমি কীভাবে আমার এইচটিসিপি স্থিতি কোড চেক করব?


আপনার এখানে একবার দেখে নেওয়া উচিত weblogs.asp.net/shijuvarghese/archive/2013/07/30/…
ভুলে

4
আপনার লিঙ্ক করা সাইটটি ওয়েব এপিআই 1 ব্যবহার করে এবং অপির প্রশ্নের কোনও প্রাসঙ্গিক প্রতিক্রিয়া নয়
ডেভিড পেডেন

উত্তর:


190

এখানে Ok()যে ধরণের OkResultপ্রতিক্রিয়া স্থিতি সেট করা হয়েছে তার জন্য এখানে কেবলমাত্র একজন সহায়ক HttpStatusCode.Ok... যাতে আপনি নিজের কর্মের ফলাফলের উদাহরণটি কিনা তা পরীক্ষা করে দেখতে পারেন OkResult... কয়েকটি উদাহরণ (লিখিত XUnit):

// if your action returns: NotFound()
IHttpActionResult actionResult = valuesController.Get(10);
Assert.IsType<NotFoundResult>(actionResult);

// if your action returns: Ok()
actionResult = valuesController.Get(11);
Assert.IsType<OkResult>(actionResult);

// if your action was returning data in the body like: Ok<string>("data: 12")
actionResult = valuesController.Get(12);
OkNegotiatedContentResult<string> conNegResult = Assert.IsType<OkNegotiatedContentResult<string>>(actionResult);
Assert.Equal("data: 12", conNegResult.Content);

// if your action was returning data in the body like: Content<string>(HttpStatusCode.Accepted, "some updated data");
actionResult = valuesController.Get(13);
NegotiatedContentResult<string> negResult = Assert.IsType<NegotiatedContentResult<string>>(actionResult);
Assert.Equal(HttpStatusCode.Accepted, negResult.StatusCode);
Assert.Equal("some updated data", negResult.Content);

66
এমএসটিস্টেAssert.IsInstanceOfType(httpActionResult, typeof(OkResult));
সানিল

2
এছাড়াও, জন্য Created<T>(url,content)তারCreatedNegotiatedContentResult
সুনীল

1
ধন্যবাদ সুনীল .. Createdসম্ভবত কোনও Getঅপারেশনের জন্য ভাল উদাহরণ ছিল না ... আমি স্ট্যাটাস কোডটি এখন আলাদা আলাদা করে দিয়েছি ...
কিরণ চালা

4
@ স্ট্যানিমির ইয়াকিমভ ফলাফলের ধরণ OkNegotiatedContentResult<T>তখন যখন আপনি কোনও ধরণের কোনও বিষয় পাস TকরেনOk()
ব্রায়ানস্টে

2
আইএইচটিপিস্ট্যাটাসকোডগুলির সাথে কোনও সহায়তা যা অনিয়মিত কোডগুলি ফেরত দেয়? 422 এর মতো? return new StatusCodeResult((HttpStatusCode)422, this);
রোবোকোজো

28

একটি মৃত প্রশ্নকে পুনরুত্থানের সময়

বর্তমানের উত্তরগুলি একটি পরিচিত ধরণের প্রতিক্রিয়া অবজেক্টটি ingালার উপর নির্ভর করে। দুর্ভাগ্যক্রমে, প্রতিক্রিয়াগুলিতে নিয়ামক বাস্তবায়নের অন্তরঙ্গ জ্ঞান ছাড়াই এটির জন্য কার্যকরী শ্রেণিবদ্ধ বা অন্তর্নিহিত রূপান্তর পথ বলে মনে হয় না। নিম্নোক্ত বিবেচনা কর:

public class MixedCodeStandardController : ApiController {

    public readonly object _data = new Object();

    public IHttpActionResult Get() {
        return Ok(_data);
    }

    public IHttpActionResult Get(int id) {
        return Content(HttpStatusCode.Success, _data);
    }
}

ক্লাস পরীক্ষা:

var testController = new MixedCodeStandardController();

var getResult = testController.Get();
var posRes = getResult as OkNegotiatedContentResult<object>;
Assert.IsType<OkNegotiatedContentResult<object>>(getResult);
Assert.AreEqual(HttpStatusCode.Success, posRes.StatusCode);
Assert.AreEqual(testController._data, posRes.Content);

var idResult = testController.Get(1);
var oddRes = getResult as OkNegotiatedContentResult<object>; // oddRes is null
Assert.IsType<OkNegotiatedContentResult<object>>(idResult); // throws failed assertion
Assert.AreEqual(HttpStatusCode.Success, oddRes.StatusCode); // throws for null ref
Assert.AreEqual(testController._data, oddRes.Content); // throws for null ref

ব্ল্যাক বক্সের বাইরে থেকে, প্রতিক্রিয়া স্ট্রিম মূলত একই। পরীক্ষাটি অবশ্যই জানতে হবে যে নিয়ামক কীভাবে রিটার্ন কলটিকে এভাবে পরীক্ষা করতে প্রয়োগ করেছিলেন।

পরিবর্তে, IHttpActionResult থেকে ফিরে আসা HTTPResponseMessage অবজেক্টটি ব্যবহার করুন। এটি নিশ্চিত করে যে পরীক্ষাটি সামঞ্জস্যপূর্ণ হতে পারে, এমনকি নিয়ামক কোডটি নাও থাকতে পারে:

var testController = new MixedCodeStandardController();

var getResult = testController.Get();
var getResponse = getResult.ExecuteAsync(CancellationToken.None).Result;
Assert.IsTrue(getResponse.IsSuccessStatusCode);
Assert.AreEqual(HttpStatusCode.Success, getResponse.StatusCode);

var idResult = testController.Get(1);
var idResponse = idResult.ExecuteAsync(CancellationToken.None).Result;
Assert.IsTrue(idResponse.IsSuccessStatusCode);
Assert.AreEqual(HttpStatusCode.Success, idResponse.StatusCode);

3
এই কাজ করার মতো একটি জিনিস পেতে আমাকে করতে হয়েছিল (IHttpActionResult.ExecuteAsync পদ্ধতিটি ব্যবহার করে) ApiController.Request এট্রিবিউটটি নীচে নির্ধারণ করা ছিল:new HttpRequestMessage() {Properties = { { HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration() } }}
tobypls

16

এটি নুনিতের জন্য অভিযোজিত কিরণ চালার গৃহীত উত্তর;

var valuesController = controller;
// if your action returns: NotFound()
IHttpActionResult actionResult = valuesController.Get(10);
var notFoundRes = actionResult as NotFoundResult;
Assert.IsNotNull(notFoundRes);

// if your action returns: Ok()
actionResult = valuesController.Get(11);
var posRes = actionResult as OkResult;
Assert.IsNotNull(posRes);

// if your action was returning data in the body like: Ok<string>("data: 12")
actionResult = valuesController.Get(12);
var conNegResult = actionResult as OkNegotiatedContentResult<string>;
Assert.IsNotNull(conNegResult);
Assert.AreEqual("data: 12", conNegResult.Content);

// if your action was returning data in the body like: Content<string>(HttpStatusCode.Accepted, "some updated data");
actionResult = valuesController.Get(13);
var negResult = actionResult as NegotiatedContentResult<string>;
Assert.IsNotNull(negResult);
Assert.AreEqual(HttpStatusCode.Accepted, negResult.StatusCode);
Assert.AreEqual("some updated data", negResult.Content);


2

যদি IHttpActionResult একটি JSON অবজেক্ট ধারণ করে, যেমন {"টোকেন": "এ"}, আমরা নিম্নলিখিত কোডটি ব্যবহার করতে পারি।

        var result = usercontroller.GetLogin("user", "password");
        Assert.IsInstanceOfType(result, typeof(OkNegotiatedContentResult<Dictionary<string,string>>));
        var content = result as OkNegotiatedContentResult<Dictionary<string, string> >;
        Assert.AreEqual("A", content.Content["token"]);

2

কয়েক ঘন্টা গবেষণা এবং চেষ্টা করার পরে, আমি অবশেষে আমার ওয়েব এপিআই 2 পদ্ধতিগুলি IHttpActionResultকীভাবে OWIN মিডলওয়্যারটি ফিরে আসবে এবং এএসপি.নেট আইডেন্টিটির ডিফল্ট বাস্তবায়ন করব তা পুরোপুরি কীভাবে পরীক্ষা করতে হবে তা আমি নির্ধারণ করেছি ।

আমি Get()নিম্নলিখিতটি পদ্ধতিটি পরীক্ষা করব ApiController:

public class AccountController : ApiController
{
    private ApplicationUserManager _userManager;
    public ApplicationUserManager UserManager => _userManager ?? HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();

    [Route("api/account"), HttpGet]
    public async Task<IHttpActionResult> Get()
    {
        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
        if (user == null)
        {
            ModelState.AddModelError(ModelStateConstants.Errors, "Account not found! Try logging out and in again.");
            return BadRequest(ModelState);
        }

        var roles = await UserManager.GetRolesAsync(user.Id);

        var accountModel = new AccountViewModel
        {
            FullName = user.FullName,
            Email = user.Email,
            Phone = user.PhoneNumber,
            Organization = user.Organization.Name,
            Role = string.Join(", ", roles)
        };

        return Ok(accountModel);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (_userManager != null)
            {
                _userManager.Dispose();
                _userManager = null;
            }
        }

        base.Dispose(disposing);
    }
}

একটি বেস ক্লাস দিয়ে শুরু করুন যা সমস্ত পরীক্ষার ক্লাস থেকে উত্তরাধিকারী হবে:

public class BaseTest
{
    protected static User CurrentUser;
    protected static IList<string> Roles;

    public BaseTest()
    {
        var email = "unit@test.com";

        CurrentUser = new User
        {
            FullName = "Unit Tester",
            Email = email,
            UserName = email,
            PhoneNumber = "123456",
            Organization = new Organization
            {
                Name = "Test Organization"
            }
        };

        Roles = new List<string>
        {
            "Administrator"
        };
    }

    protected void InitializeApiController(ApiController apiController)
    {
        //Init fake controller Http and Identity data
        var config = new HttpConfiguration();
        var request = new HttpRequestMessage();
        var routeData = new HttpRouteData(new HttpRoute(""));
        apiController.ControllerContext = new HttpControllerContext(config, routeData, request)
        {
            Configuration = config
        };

        apiController.User = new GenericPrincipal(new GenericIdentity(""), new[] { "" });

        //Initialize Mocks
        var appUserMgrMock = GetMockedApplicationUserManager();
        var appSignInMgr = GetMockedApplicationSignInManager(appUserMgrMock);
        var appDbContext = GetMockedApplicationDbContext();

        //Configure HttpContext.Current.GetOwinContext to return mocks
        var owin = new OwinContext();
        owin.Set(appUserMgrMock.Object);
        owin.Set(appSignInMgr.Object);
        owin.Set(appDbContext.Object);

        HttpContext.Current = new HttpContext(new HttpRequest(null, "http://test.com", null), new HttpResponse(null));
        HttpContext.Current.Items["owin.Environment"] = owin.Environment;
    }

    private static Mock<ApplicationSignInManager> GetMockedApplicationSignInManager(Mock<ApplicationUserManager> appUserMgrMock)
    {
        var authMgr = new Mock<Microsoft.Owin.Security.IAuthenticationManager>();
        var appSignInMgr = new Mock<ApplicationSignInManager>(appUserMgrMock.Object, authMgr.Object);

        return appSignInMgr;
    }

    private Mock<ApplicationUserManager> GetMockedApplicationUserManager()
    {
        var userStore = new Mock<IUserStore<User>>();
        var appUserMgr = new Mock<ApplicationUserManager>(userStore.Object);
        appUserMgr.Setup(aum => aum.FindByIdAsync(It.IsAny<string>())).ReturnsAsync(CurrentUser);
        appUserMgr.Setup(aum => aum.GetRolesAsync(It.IsAny<string>())).ReturnsAsync(Roles);

        return appUserMgr;
    }

    private static Mock<ApplicationDbContext> GetMockedApplicationDbContext()
    {
        var dbContext = new Mock<ApplicationDbContext>();
        dbContext.Setup(dbc => dbc.Users).Returns(MockedUsersDbSet);

        return dbContext;
    }

    private static IDbSet<User> MockedUsersDbSet()
    {
        var users = new List<User>
        {
            CurrentUser,
            new User
            {
                FullName = "Testguy #1",
                Email = "test@guy1.com",
                UserName = "test@guy1.com",
                PhoneNumber = "123456",
                Organization = new Organization
                {
                    Name = "Test Organization"
                }
            }
        }.AsQueryable();

        var usersMock = new Mock<DbSet<User>>();
        usersMock.As<IQueryable<User>>().Setup(m => m.Provider).Returns(users.Provider);
        usersMock.As<IQueryable<User>>().Setup(m => m.Expression).Returns(users.Expression);
        usersMock.As<IQueryable<User>>().Setup(m => m.ElementType).Returns(users.ElementType);
        usersMock.As<IQueryable<User>>().Setup(m => m.GetEnumerator()).Returns(users.GetEnumerator);

        return usersMock.Object;
    }
}

InitializeApiControllerপদ্ধতি মাংস ও আলু রয়েছে।

এখন আমরা আমাদের পরীক্ষাগুলি এর জন্য লিখতে পারি AccountController:

public class AccountControllerTests : BaseTest
{
    private readonly AccountController _accountController;

    public AccountControllerTests()
    {
        _accountController = new AccountController();
        InitializeApiController(_accountController);
    }

    [Test]
    public async Task GetShouldReturnOk()
    {
        var result = await _accountController.Get();
        var response = await result.ExecuteAsync(CancellationToken.None);
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
    }
}

সমস্ত কিছু কাজ করার জন্য আপনাকে একটি গুচ্ছ Microsoft.OWIN.*এবং Microsoft.AspNet.*প্যাকেজ ইনস্টল করতে হবে , আমি packages.configএখানে আমার পেস্ট করব :

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Castle.Core" version="4.3.1" targetFramework="net472" />
  <package id="EntityFramework" version="6.2.0" targetFramework="net472" />
  <package id="Microsoft.AspNet.Identity.Core" version="2.2.2" targetFramework="net472" />
  <package id="Microsoft.AspNet.Identity.EntityFramework" version="2.2.2" targetFramework="net472" />
  <package id="Microsoft.AspNet.Identity.Owin" version="2.2.2" targetFramework="net472" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.7" targetFramework="net472" />
  <package id="Microsoft.Owin" version="4.0.1" targetFramework="net472" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="4.0.1" targetFramework="net472" />
  <package id="Microsoft.Owin.Security" version="4.0.1" targetFramework="net472" />
  <package id="Microsoft.Owin.Security.Cookies" version="4.0.1" targetFramework="net472" />
  <package id="Microsoft.Owin.Security.OAuth" version="4.0.1" targetFramework="net472" />
  <package id="Moq" version="4.10.1" targetFramework="net472" />
  <package id="Newtonsoft.Json" version="12.0.1" targetFramework="net472" />
  <package id="NUnit" version="3.11.0" targetFramework="net472" />
  <package id="Owin" version="1.0" targetFramework="net472" />
  <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" />
  <package id="System.Threading.Tasks.Extensions" version="4.5.2" targetFramework="net472" />
</packages>

পরীক্ষাটি খুব সহজ, তবে প্রদর্শিত হয় যে সমস্ত কিছুই কাজ করে :-)

শুভ পরীক্ষা!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.