Controller 객체를 사용해서 각 method를 테스트하는 방법은 매우 뛰어난 테스팅 방법이지만, 불행하게도 Session 및 Identify에 대한 내용을 같이 테스팅 하는 것은 불가능하다. 특히, Session에 Wizard Data 또는 사용자에 따른 개인 정보를 저장하고 있는 경우에는 Controller 객체만을 사용하는 것은 불가능하다.
그래서, Mock을 이용해서 HttpContext를 구성하고, 구성된 HttpContext를 ControllerContext로 구성하여 Controller를 사용하게 되면 위와 같은 문제를 모두 해결 할 수 있다.
사용 방법은 다음과 같다.
그래서, Mock을 이용해서 HttpContext를 구성하고, 구성된 HttpContext를 ControllerContext로 구성하여 Controller를 사용하게 되면 위와 같은 문제를 모두 해결 할 수 있다.
01.
public
class
FakeSession : HttpSessionStateBase
02.
{
03.
private
readonly
SessionStateItemCollection _sessionItems;
04.
public
FakeSession(SessionStateItemCollection sessionItems)
05.
{
06.
_sessionItems = sessionItems;
07.
}
08.
09.
public
override
void
Add(
string
name,
object
value)
10.
{
11.
_sessionItems[name] = value;
12.
}
13.
14.
public
override
int
Count
15.
{
16.
get
17.
{
18.
return
_sessionItems.Count;
19.
}
20.
}
21.
22.
public
override
IEnumerator GetEnumerator()
23.
{
24.
return
_sessionItems.GetEnumerator();
25.
}
26.
27.
public
override
NameObjectCollectionBase.KeysCollection Keys
28.
{
29.
get
30.
{
31.
return
_sessionItems.Keys;
32.
}
33.
}
34.
35.
public
override
object
this
[
string
name]
36.
{
37.
get
38.
{
39.
return
_sessionItems[name];
40.
}
41.
set
42.
{
43.
_sessionItems[name] = value;
44.
}
45.
}
46.
47.
public
override
object
this
[
int
index]
48.
{
49.
get
50.
{
51.
return
_sessionItems[index];
52.
}
53.
set
54.
{
55.
_sessionItems[index] = value;
56.
}
57.
}
58.
public
override
void
Remove(
string
name)
59.
{
60.
_sessionItems.Remove(name);
61.
}
62.
}
63.
64.
protected
T GetContextedController<t>(T controller,
string
userName, FakeSession sessionState) where T : ControllerBase
65.
{
66.
//Register Route
67.
RouteCollection routes =
new
RouteCollection();
68.
MvcApplication.RegisterRoutes(routes);
69.
70.
//Build Mock HttpContext, Request, Response
71.
var mockHttpContext =
new
Moq.Mock<httpcontextbase>();
72.
var mockRequest =
new
Moq.Mock<httprequestbase>();
73.
var mockResponse =
new
Moq.Mock<httpresponsebase>();
74.
75.
//Setup Mock HttpContext
76.
mockHttpContext.Setup(x => x.Request).Returns(mockRequest.Object);
77.
mockHttpContext.Setup(x => x.Response).Returns(mockResponse.Object);
78.
mockHttpContext.Setup(x => x.Session).Returns(sessionState);
79.
80.
if
(
string
.IsNullOrEmpty(userName))
81.
{
82.
mockHttpContext.Setup(x => x.User.Identity.IsAuthenticated).Returns(
false
);
83.
mockRequest.Setup(x => x.IsAuthenticated).Returns(
false
);
84.
}
85.
else
86.
{
87.
mockHttpContext.Setup(x => x.User.Identity.Name).Returns(userName);
88.
mockHttpContext.Setup(x => x.User.Identity.IsAuthenticated).Returns(
true
);
89.
mockRequest.Setup(x => x.IsAuthenticated).Returns(
true
);
90.
}
91.
mockRequest.Setup(x => x.ApplicationPath).Returns(
"/"
);
92.
93.
// Build Request Context
94.
var ctx =
new
RequestContext(mockHttpContext.Object,
new
RouteData());
95.
controller.ControllerContext =
new
ControllerContext(ctx, controller);
96.
return
controller;
97.
}
98.
</httpresponsebase></httprequestbase></httpcontextbase></t>
사용 방법은 다음과 같다.
01.
[Test]
02.
public
void
Start()
03.
{
04.
_controller =
new
VirtualMachineController();
05.
SessionStateItemCollection sessionItemCollections =
new
SessionStateItemCollection();
06.
sessionItemCollections[SessionConstants.Account] = _account;
07.
sessionItemCollections[SessionConstants.ZoneList] = tempZoneList;
08.
09.
_session =
new
FakeSession(sessionItemCollections);
10.
_controller = GetContextedController(_controller, LocalConf.AccountName, _session);
11.
_controller.Start(
"tempVmName"
);
12.
}