5

所以我正在为我们的 MVC4 应用程序编写测试,并且我正在专门测试控制器操作。正如我在标题中提到的,测试仍然命中服务 (WCF) 而不是返回测试数据。我有这个控制器:

public class FormController : Controller
{
    public SurveyServiceClient Service { get; set; }
    public SurveyDao Dao { get; set; }

    public FormController(SurveyServiceClient service = null, SurveyDao dao = null)
    {
        this.Service = service ?? new SurveyServiceClient();
        this.Dao = dao ?? new SurveyDao(Service);
    }

    //
    // GET: /Form/

    public ActionResult Index()
    {
        var formsList = new List<FormDataTransformContainer>();
        Dao.GetForms().ForEach(form => formsList.Add(form.ToContainer()));

        var model = new IndexViewModel(){forms = formsList};
        return View("Index", model);
    }

它使用这个 DAO 对象:

public class SurveyDao
{
    private readonly SurveyServiceClient _service;
    private readonly string _authKey;

    public SurveyDao(SurveyServiceClient serviceClient)
    {
        _service = serviceClient;
    }

    ....

    public FormContract[] GetForms()
    {
        var forms = _service.RetrieveAllForms();
        return forms;
    }

这是我使用 JustMock 进行的测试,GetForms() 上的模拟在帮助程序类中返回一些测试数据:

[TestClass]
public class FormControllerTest
{
    private SurveyDao mockDao;
    private SurveyServiceClient mockClient;

    public FormControllerTest()
    {
        mockClient = Mock.Create<SurveyServiceClient>();
        mockDao = Mock.Create<SurveyDao>(mockClient);
    }

    [TestMethod]
    public void TestIndexAction() 
    {
        //Arrange
        var controller = new FormController(mockClient, mockDao);
        Mock.Arrange(() => mockDao.GetForms()).Returns(TestHelpers.FormContractArrayHelper);

        //Act
        var result = controller.Index() as ViewResult;

        //Assert
        Assert.IsInstanceOfType(result.Model, typeof(IndexViewModel));
    }
}

我的问题是,当我运行测试时,服务仍在被调用。我已经使用 Fiddler 验证了这一点,并调试了测试并检查了用我们服务的测试数据填充的“结果”的值。

编辑:

我已将测试构造函数更改为 [TestInitialize] 函数,因此测试现在看起来像这样:

[TestClass]
public class FormControllerTest
{
    private SurveyDao mockDao;
    private SurveyServiceClient mockClient;

    [TestInitialize]
    public void Initialize()
    {
        mockClient = Mock.Create<SurveyServiceClient>();
        mockDao = Mock.Create<SurveyDao>(Behavior.Strict);
    }

    [TestMethod]
    public void TestIndexAction() 
    {
        //Arrange
        var controller = new FormController(mockClient, mockDao);
        Mock.Arrange(() => mockDao.GetForms()).Returns(TestHelpers.FormContractArrayHelper);

        //Act
        var result = controller.Index() as ViewResult;

        //Assert
        Assert.IsInstanceOfType(result.Model, typeof(IndexViewModel));
    }
}
4

2 回答 2

3

请确认您为 JustMock 使用了正确的程序集。有几个不同的(VisualBasic、Silverlight、JustMock)。JustMock 是您应该包含在项目中的一个。

未能包含正确的行为将导致您描述的行为(方法未正确存根)。

于 2013-10-15T14:54:27.507 回答
1

JustMock手册解释(我强调):

默认情况下 Telerik JustMock 使用松散的模拟,并允许您调用 给定类型的任何方法无论方法调用是否安排,您都可以调用它。

您可以在调用Create()Mock 的方法时控制此行为:

var foo = Mock.Create<IFoo>(Behavior.Strict);

如果您没有显式实现某个方法,您可以在那里指定模拟对象应该做什么。在您的情况下(我认为这是默认行为),模拟确实调用了您要模拟的对象的原始方法。

Behavior Enumeration您在枚举中有以下选择:

  • Loose:指定默认情况下模拟调用的行为类似于存根,除非显式设置。
  • RecursiveLoose:指定默认情况下模拟调用将返回模拟对象,除非显式设置。
  • Strict:指定对 mock 进行的任何调用如果未明确设置将引发异常。
  • CallOriginal:指定默认情况下,在 mock 上进行的所有调用都将调用其相应的原始成员,除非设置了一些期望。
于 2013-10-14T16:28:06.660 回答