I love commercial version of Telerik JustMock just because of partial method mocking feature. You can test one method and mock other calls within that class,so you can have unit tests for each method.
I have a helper class to build HttpContext. You may need that to check viewresults, session and similar data. These simple examples will show arrange, assert, and partial method mocking.
1: public class HttpContextTelerikMock
2: {
3:
4:
5:
6: public HttpContextBase MockContext { get; set; }
7: public HttpRequestBase MockRequest { get; set; }
8: public HttpResponseBase MockResponse { get; set; }
9: public HttpSessionStateBase MockSession { get; set; }
10: public HttpServerUtilityBase MockServer { get; set; }
11: public IPrincipal MockUser { get; set; }
12: public IIdentity MockIdentity { get; set; }
13:
14:
15: public HttpContextTelerikMock()
16: {
17: //do nothing
18: }
19:
20: public void SetupSessionOnly(Dictionary<string, string> sessionStubs )
21: {
22:
23: MockContext = Mock.Create<HttpContextBase>();
24: foreach (KeyValuePair<string, string> keyValuePair in sessionStubs)
25: {
26: Mock.Arrange(() => MockContext.Session[keyValuePair.Key]).Returns(keyValuePair.Value);
27:
28: }
29: }
30:
31: /// <summary>
32: /// Basic mocks for response, request,session, and server
33: /// </summary>
34: public void BareInit()
35: {
36: MockContext = Mock.Create<HttpContextBase>();
37: MockRequest = Mock.Create<HttpRequestBase>();
38: MockResponse = Mock.Create<HttpResponseBase>();
39: MockSession = Mock.Create<HttpSessionStateBase>();
40: MockServer = Mock.Create<HttpServerUtilityBase>();
41:
42:
43: Mock.Arrange(()=> MockContext.Request).Returns(MockRequest);
44: Mock.Arrange(()=> MockContext.Response).Returns(MockResponse);
45: Mock.Arrange(()=> MockContext.Session).Returns(MockSession);
46: Mock.Arrange(()=> MockContext.Server).Returns(MockServer);
47:
48: }
49:
50: public HttpContextBase SetupCurrentUser(string username)
51: {
52: //Context.User
53: MockContext = Mock.Create<HttpContextBase>();
54: MockRequest = Mock.Create<HttpRequestBase>();
55: MockResponse = Mock.Create<HttpResponseBase>();
56: var MockUser = Mock.Create<IPrincipal>();
57: var MockIdentity = Mock.Create<IIdentity>();
58: Mock.Arrange(()=> MockContext.User).Returns(MockUser);
59: Mock.Arrange(()=> MockUser.Identity).Returns(MockIdentity);
60: Mock.Arrange(()=> MockUser.Identity.Name).Returns(username);
61:
62: //Request
63: Mock.Arrange(()=> MockRequest.InputStream).Returns(new MemoryStream());
64:
65: //Response
66: Mock.Arrange(()=> MockResponse.OutputStream).Returns(new MemoryStream());
67: return MockContext;
68: }
69: }
You can extend this to arrange httpcontext for different requirements.
In this simple example, I want to arrange a another method inside this controller to return a specific response,so i can test single method not all the related calls.
I have interfaces for Repositories to mock their behavior. In this example, "setupRepo" will be a mock object to prevent direct database call in the controller. Our goal is to test only this specific method not all related calls.
1: public IBillerSetupRepo setupRepo;
2: //
3: // GET: /Default1/Edit/5
4: public ActionResult Edit(Guid id)
5: {
6: string username = User.Identity.Name;
7: if (HasAccessToBiller(username, id))
8: {
9: Biller biller = setupRepo.GetBiller(id);
10: return View(biller.ToModelView());
11: }
12: else
13: {
14: return View("NotAuthorized");
15: }
16:
17: }
We are returning two different views: notauthorized and edit with model. First test checks the unauthorized view. It will return this view, if user does not have access to this biller.
1: [Test]
2: public void Edit_SendNotAuthorized()
3: {
4: BillerController target= new BillerController();
5: Guid billerid = Guid.NewGuid();
6: string username = "Test234";
7: //partial method mock
8: Mock.Arrange(() => target.HasAccessToBiller(username, billerid)).Returns(false);
9:
10: //context adjustment
11: HttpContextTelerikMock helper = new HttpContextTelerikMock();
12: target.ControllerContext = new ControllerContext(helper.SetupCurrentUser(username), new RouteData(), target);
13:
14: //Check viewpage
15: ViewResult result = target.Edit(billerid) as ViewResult;
16: Assert.AreEqual("NotAuthorized", result.ViewName);
17:
18:
19: }
Second call will check the call, if user has access to this biller:
1: [Test]
2: public void Edit_HasAccess_SendModelTOView()
3: {
4: IBillerSetupRepo mocksetuprepo = Mock.Create<IBillerSetupRepo>();
5: BillerController target = new BillerController();
6: Guid billerid = Guid.NewGuid();
7: string username = "Test234";
8: Biller testbiller = new Biller
9: {
10: BillerName = "Testbiller2xbv342342"
11: };
12: //partial method mock
13: Mock.Arrange(() => target.HasAccessToBiller(username, billerid)).Returns(true);
14: //Arrange repo to return our model
15: Mock.Arrange(() => mocksetuprepo.GetBiller(billerid)).Returns(testbiller);
16: HttpContextTelerikMock helper = new HttpContextTelerikMock();
17: target.ControllerContext = new ControllerContext(helper.SetupCurrentUser(username), new RouteData(), target);
18: target.setupRepo = mocksetuprepo;
19:
20:
21: ViewResult result = target.Edit(billerid) as ViewResult;
22: Assert.AreEqual(testbiller.BillerName, ((BillerView)result.Model).BillerName);
23: //Assert that mock object was called
24: Mock.Assert(() => mocksetuprepo.GetBiller(billerid), Occurs.Once());
25:
26: }
No comments:
Post a Comment
Hey!
Let me know what you think?