鉴于我有一个控制器类:
public class ResourceController : AuthorizedController
{
public virtual string Resource()
{
//do magic
}
public virtual string ResourceParent()
{
var url = Resource();
return url;
}
}
}
使用测试工具:
[Subject(typeof (ResourceController))]
public class When_I_want_the_parent_resource : WithSubject<ResourceController>
{
private static readonly string ParentUrl = "/organizations/1";
private static readonly string ResourceUrl = "/organizations/1/contacts/1";
private static string _result;
private Establish context = () =>
{
The<ResourceController>()
.WhenToldTo(x => x.Resource())
.Return(ResourceUrl);
};
private Because of = () => _result = Subject.ResourceParent();
private It should_match_the_expected_parent_url = () =>
_result.ShouldEqual(ParentUrl);
}
此单元测试将失败,因为Subject.ResourceParent()将返回null,因为Machine.Fakes已自动插入此方法。作为临时解决方法,我刚刚从ResourceParent中删除了虚拟关键字,以便能够测试我的代码。我认为必须有一个真正的解决方案让我告诉Machine.Fakes不要覆盖ResourceParent()
答案 0 :(得分:3)
实际上在Machine.Fakes中没有“真正的”解决方案。我认为你需要重新考虑你的夹具设计。
首先,正如蒂姆已经指出的那样,你不应该伪造任何关于这个主题的方法。相反,您应该伪造控制器的依赖关系并按规范使用控制器。 “The”方法的预期用法是访问规范中主题的依赖关系,但您在规范中尝试的是访问主题本身。我认为那是出问题的地方。 &lt; ResourceController&gt;和主题实际上是单独的实例。这就是为什么配置交互不会发生的原因。
只需在代码中解决此问题的一些选项:
HTH,
比约恩
答案 1 :(得分:2)
如果您正在测试控制器,那么也许您不应该创建该控制器的模拟或伪造 。否则你只是测试一个模拟而且测试确实没有任何效力。
模拟或伪造控制器的依赖项。测试真实的控制器。
答案 2 :(得分:0)
最后,我最终将这个测试从Machine.Fakes中拉出来并将其放入常规单元测试中。然后我直接使用Moq来配置HttpRequestBase
种子数据,然后手动创建我的控制器类并调用它上面的方法。