মক এইচটিটিপি কনটেক্সট. টেস্ট ইনিশ পদ্ধতিতে বর্তমান


177

আমি যে এএসপি.এনইটি এমভিসি অ্যাপ্লিকেশনটি তৈরি করেছি তাতে ইউনিট টেস্টিং যুক্ত করার চেষ্টা করছি। আমার ইউনিট পরীক্ষায় আমি নিম্নলিখিত কোডটি ব্যবহার করি:

[TestMethod]
public void IndexAction_Should_Return_View() {
    var controller = new MembershipController();
    controller.SetFakeControllerContext("TestUser");

    ...
}

নিয়ামক প্রসঙ্গে উপহাস করার জন্য নিম্নলিখিত সহায়কগুলির সাথে:

public static class FakeControllerContext {
    public static HttpContextBase FakeHttpContext(string username) {
        var context = new Mock<HttpContextBase>();

        context.SetupGet(ctx => ctx.Request.IsAuthenticated).Returns(!string.IsNullOrEmpty(username));

        if (!string.IsNullOrEmpty(username))
            context.SetupGet(ctx => ctx.User.Identity).Returns(FakeIdentity.CreateIdentity(username));

        return context.Object;
    }

    public static void SetFakeControllerContext(this Controller controller, string username = null) {
        var httpContext = FakeHttpContext(username);
        var context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
        controller.ControllerContext = context;
    }
}

এই পরীক্ষার শ্রেণিটি একটি বেস ক্লাসের উত্তরাধিকার সূত্রে প্রাপ্ত যা নিম্নলিখিত:

[TestInitialize]
public void Init() {
    ...
}

এই পদ্ধতির অভ্যন্তরে এটি একটি লাইব্রেরি কল করে (যার উপরে আমার কোনও নিয়ন্ত্রণ নেই) যা নিম্নলিখিত কোডটি চালানোর চেষ্টা করে:

HttpContext.Current.User.Identity.IsAuthenticated

এখন আপনি সম্ভবত সমস্যাটি দেখতে পাচ্ছেন। আমি নিয়ন্ত্রকের বিরুদ্ধে জাল এইচটিপিপি কনটেক্সট সেট করেছি তবে এই বেস ইন্স পদ্ধতিতে নয়। ইউনিট টেস্টিং / উপহাস আমার কাছে খুব নতুন তাই আমি নিশ্চিত করতে চাই যে আমি এই অধিকার পেয়েছি। এইচটিটিপি কনটেক্সটকে মক আউট করার জন্য আমার সঠিক উপায় কী তা যাতে এটি আমার নিয়ামক এবং যে কোনও লাইব্রেরি যা আমার উদ্যোগ পদ্ধতিতে ডাকা হয় সেগুলি জুড়ে ভাগ করা যায়।

উত্তর:


362

HttpContext.Currentএর উদাহরণ System.Web.HttpContextদেয় যা প্রসারিত হয় না System.Web.HttpContextBase। উপহাস করা কঠিন বলে সম্বোধন করার HttpContextBaseজন্য পরে যুক্ত করা হয়েছিল HttpContext। দুটি ক্লাস মূলত সম্পর্কিত নয় ( HttpContextWrapperতাদের মধ্যে অ্যাডাপ্টার হিসাবে ব্যবহৃত হয়)।

ভাগ্যক্রমে, আপনি HttpContextনিজেই IPrincipal(ব্যবহারকারী) এবং এর প্রতিস্থাপনের জন্য যথেষ্ট নকল IIdentity

নিম্নলিখিত কোডটি প্রত্যাশার মতো চলে, এমনকি কোনও কনসোল অ্যাপ্লিকেশনটিতে:

HttpContext.Current = new HttpContext(
    new HttpRequest("", "http://tempuri.org", ""),
    new HttpResponse(new StringWriter())
    );

// User is logged in
HttpContext.Current.User = new GenericPrincipal(
    new GenericIdentity("username"),
    new string[0]
    );

// User is logged out
HttpContext.Current.User = new GenericPrincipal(
    new GenericIdentity(String.Empty),
    new string[0]
    );

চিয়ারস তবে আমি কীভাবে কোনও লগ-আউট ব্যবহারকারীর জন্য এটি সেট করতে পারি?
nfplee

5
@nfplee - আপনি মধ্যে একটি খালি স্ট্রিং পাস যদি GenericIdentityকন্সট্রাকটর, IsAuthenticatedমিথ্যা ফিরে আসবে
রিচার্ড Szalay

2
এটি কি এইচটিটিপি কনটেক্সটে ক্যাশে উপহাস করার জন্য ব্যবহার করা যেতে পারে?
ডেভডেভ

1
হ্যাঁ, এটা পারে। ধন্যবাদ!
ডেভডাভ

4
@ সিআরএনজি - এমভিসি ব্যবহার করে HttpContextBase, যা উপহাস করা যায়। আপনি যদি এমভিসি ব্যবহার করে থাকেন তবে আমি যে ওয়ার্কআউন্ড পোস্ট করেছি তা ব্যবহার করার দরকার নেই। আপনি যদি এটির সাথে এগিয়ে যান, আপনি সম্ভবত নিয়ন্ত্রক তৈরি করার আগে আপনার পোস্ট করা কোডটি চালানো দরকার ।
রিচার্ড জাজাল

35

টেস্ট ইনিশের নীচেও কাজটি করবে।

[TestInitialize]
public void TestInit()
{
  HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));
  YourControllerToBeTestedController = GetYourToBeTestedController();
}

আমার সমাধানে পৃথক পরীক্ষামূলক প্রকল্পে আমি HTTPContext এ ঠিকানা পেতে পারি না। আপনি কি নিয়ামকের উত্তরাধিকার সূত্রে তা পেতে সক্ষম?
জন পিটারস

1
System.Webআপনার পরীক্ষা প্রকল্পে আপনার কি রেফারেন্স রয়েছে ?
পিইজিজি

হ্যাঁ তবে আমার প্রকল্পটি একটি এমভিসি প্রকল্প, এটি কি সম্ভব? সিস্টেমের এমভিসি সংস্করণটি e ওয়েবে কেবল সেই নেমস্পেসের একটি উপসেট রয়েছে?
জন পিটার্স

2
@ ব্যবহারকারী 1522548 (আপনার একটি অ্যাকাউন্ট তৈরি করা উচিত) অ্যাসেম্বলি সিস্টেম.ওয়েব.ডিল, ভি 4.0.0.0 এর অবশ্যই এইচটিটিপি কনটেক্সট রয়েছে আমি কেবল আমার উত্স কোডটি যাচাই করেছি।
PUG

আমার ভুল, আমার ফাইলটিতে সিস্টেম.সাহাবি.এমভিসি এবং নোট সিস্টেম.ওয়েব-তে একটি উল্লেখ রয়েছে। আপনার সাহায্যের জন্য ধন্যবাদ.
জন পিটারস

7

আমি জানি এটি একটি পুরানো বিষয়, তবে ইউনিট পরীক্ষার জন্য এমভিসি অ্যাপ্লিকেশনকে উপহাস করা আমরা খুব নিয়মিত ভিত্তিতে করি is

আমি কেবল ভিজ্যুয়াল স্টুডিও ২০১৩-তে আপগ্রেড করার পরে এমকিসি 3 ব্যবহার করে একটি এমভিসি 3 অ্যাপ্লিকেশনকে উপহাস করার জন্য আমার অভিজ্ঞতাগুলি যুক্ত করতে চেয়েছিলাম the ভেরিয়েবলগুলি দেখার জন্য যখন ইউনিট পরীক্ষাগুলির কোনওটিই ডিবাগ মোডে কাজ করছিল না এবং এইচটিটিপি কনটেক্সট "এক্সপ্রেশনকে মূল্যায়ন করতে পারেনি" দেখিয়েছিল ।

ভিজ্যুয়াল স্টুডিও 2013 এ পরিণত হয়েছে কিছু বিষয়বস্তু মূল্যায়ন করার সমস্যা রয়েছে। বিদ্রূপযুক্ত ওয়েব অ্যাপ্লিকেশনগুলিতে আবার কাজ করার জন্য, আমাকে সরঞ্জামগুলি => বিকল্পগুলি => ডিবাগিং => সাধারণ সেটিংসে "পরিচালিত সামঞ্জস্যতা মোড ব্যবহার করুন" পরীক্ষা করতে হয়েছিল।

আমি সাধারণত এ জাতীয় কিছু করি:

public static class FakeHttpContext
{
    public static void SetFakeContext(this Controller controller)
    {

        var httpContext = MakeFakeContext();
        ControllerContext context =
        new ControllerContext(
        new RequestContext(httpContext,
        new RouteData()), controller);
        controller.ControllerContext = context;
    }


    private static HttpContextBase MakeFakeContext()
    {
        var context = new Mock<HttpContextBase>();
        var request = new Mock<HttpRequestBase>();
        var response = new Mock<HttpResponseBase>();
        var session = new Mock<HttpSessionStateBase>();
        var server = new Mock<HttpServerUtilityBase>();
        var user = new Mock<IPrincipal>();
        var identity = new Mock<IIdentity>();

        context.Setup(c=> c.Request).Returns(request.Object);
        context.Setup(c=> c.Response).Returns(response.Object);
        context.Setup(c=> c.Session).Returns(session.Object);
        context.Setup(c=> c.Server).Returns(server.Object);
        context.Setup(c=> c.User).Returns(user.Object);
        user.Setup(c=> c.Identity).Returns(identity.Object);
        identity.Setup(i => i.IsAuthenticated).Returns(true);
        identity.Setup(i => i.Name).Returns("admin");

        return context.Object;
    }


}

এবং প্রসঙ্গে এই মত সূচনা

FakeHttpContext.SetFakeContext(moController);

এবং নিয়ামক সরাসরি পদ্ধতিতে কল কল

long lReportStatusID = -1;
var result = moController.CancelReport(lReportStatusID);

গৃহীত উত্তরের তুলনায় এটিকে সেট করার কোনও ভাল কারণ আছে কি? ব্যাট বন্ধ এটি আরও জটিল বলে মনে হচ্ছে এবং এটি কোনও অতিরিক্ত সুবিধা দেয় বলে মনে হয় না।
kilkfoe

1
এটি আরও বিশদ / মডুলার বিদ্রূপের পদ্ধতি সরবরাহ করে
ভিনসেন্ট বাসকার্লো

4

যদি আপনার অ্যাপ্লিকেশন তৃতীয় পক্ষটি অভ্যন্তরীণভাবে পুনঃনির্দেশিত হয়, তাই নীচের উপায়ে HttpContext উপহাস করা ভাল:

HttpWorkerRequest initWorkerRequest = new SimpleWorkerRequest("","","","",new StringWriter(CultureInfo.InvariantCulture));
System.Web.HttpContext.Current = new HttpContext(initWorkerRequest);
System.Web.HttpContext.Current.Request.Browser = new HttpBrowserCapabilities();
System.Web.HttpContext.Current.Request.Browser.Capabilities = new Dictionary<string, string> { { "requiresPostRedirectionHandling", "false" } };
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.