我正在使用DotNetOpenAuth CTP库实现oauth提供程序。因此,我创建了一个mvc3应用程序,它有一个OAuth控制器,其中包含3种方法,目的是授权第三方应用程序。控制器有一个IOAuthService,它封装了库为完成某些任务必须执行的所有逻辑,但是服务方法返回具有构造函数保护的DotNetOpenOAuth对象。
我想在我的OAuthController中测试这些方法的行为,为此,我试图模拟我的服务方法,但我无法做到这一点。我必须告诉moq库我期望服务方法返回哪种类型的对象,而且由于我不能访问这些对象的构造函数,所以我无法对我的控制器方法执行测试。
控制员:
public class OAuthController : Controller
{
private readonly IOAuthService _oAuthService;
public OAuthController(IOAuthService oAuthService)
{
_oAuthService = oAuthService;
}
[Authorize, AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public ActionResult Authorize()
{
ClientApplication requestingClient;
var request = _oAuthService.ReadAuthorizationRequest();
if (request == null)
{
throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
}
var response = _oAuthService.RequestClientAuthorization(GetIdentity().Name, out requestingClient, request);
if (response != null)
{
return response.AsActionResult();
}
var model = new AuthorizeClientApplicationViewModel
{
ClientApplication = requestingClient.Name,
Scope = request.Scope,
AuthorizationRequest = request,
};
return View(model);
}
public virtual IIdentity GetIdentity()
{
return User.Identity;
}
}我想测试的是,每当第三方应用没有授权时,用户就会弹出一个视图,请求他授权该应用程序。为此,我需要嘲笑:
然后,我的测试方法的设置将类似于:
var oAuthService = new Mock<IOAuthService>();
oAuthService.Setup(a => a.RequestClientAuthorization(userName, out client, pendingRequest)).Returns(new OutgoingWebResponse()); // DotNetOpenAuth doesn't allow me to do the **new OutgoingWebResponse**PD:对于这个问题,我只写了一种控制器方法,但是有3种,它们有类似的场景。
发布于 2012-01-18 16:32:48
一种可能是编写一个包装器(就像ASP.NET MVC抽象所有特定于HTTP的内容一样):
public abstract class OutgoingWebResponseWrapperBase
{
protected OutgoingWebResponseWrapperBase() { }
public abstract ActionResult AsActionResult();
}然后有一个天真的实现:
public class OutgoingWebResponseWrapper: OutgoingWebResponseWrapperBase
{
private readonly OutgoingWebResponse _response;
public OutgoingWebResponseWrapper(OutgoingWebResponse response)
{
_response = response;
}
public override ActionResult AsActionResult()
{
return _response.AsActionResult();
}
}现在修改IOAuthService.RequestClientAuthorization方法以返回一个OutgoingWebResponseWrapperBase而不是OutgoingWebResponse。
就像这样:
public interface IOAuthService
{
...
OutgoingWebResponseWrapperBase RequestClientAuthorization(...);
}显然,您的控制器代码将完全保持不变。现在您可以在单元测试中模拟RequestClientAuthorization的返回类型了,因为它是一个抽象类。您还可以模拟AsActionResult抽象方法调用以返回一些预期的模拟实例,并且您将在单元测试中断言您正在测试的控制器操作返回了这个预期的操作结果。
发布于 2012-01-18 16:30:14
如果构造函数受到保护,则派生类型可以访问它。您能否简单地使用Moq创建一个OutgoingWebResponse的模拟(内部将使Moq派生并调用我认为的受保护的构造函数)并从模拟方法实现中返回它?
就像这样:
System.Net.HttpWebResponse mockResponse; // get this from somewhere
new Moq.Mock<DotNetOpenAuth.Messaging.OutgoingWebResponse>(mockResponse, 5);这应该可以让您模拟一个OutgoingWebResponse。下一个问题是,在哪里得到yoru HttpWebResponse实例,因为它也只有一个受保护的构造函数。您可以继续这条链,并模拟出与OutgoingWebResponse相同的内容,并查看您取得的进展。
https://stackoverflow.com/questions/8913187
复制相似问题