单元测试一个方法,该方法调用另一个返回null的方法,无论如何

时间:2014-07-21 13:53:02

标签: c# unit-testing null nunit rhino-mocks

我的控制器中有一个方法。

public JsonResult GetMemberSubgroupSpecifications(int rows, int page)
    {
        List<VersionSpecification> versionSpecifications = _sessionAccessor.Contract.VersionSpecifications
            .Where(x => x.SpecificationType.Id == (int)SpecificationTypes.MemberSubGroup).ToList();
        List<MemberSubGroup> subGroups = _sessionAccessor.MemberSubGroups;

        if (subGroups == null)
        {
            subGroups = _subGroups.GetMemberSubGroups();
        }
        else if (subGroups.Count == 0)
        {
            subGroups = _subGroups.GetMemberSubGroups();
        }

        var specificationValues = versionSpecifications.GroupBy(x => x.Value).ToDictionary(r => r.Key, z => z.First());

        List<MemberSubGroup> contractMemberSubGroups = subGroups.Where(x => specificationValues.ContainsKey(x.Id)).ToList();

        _sessionAccessor.MemberSubGroups = contractMemberSubGroups;

        var jsonData = contractMemberSubGroups.Select(x => new
        {
            Id = x.Id,
            MemberSubGroupName = x.SubGroupName,
            MemberGroupName = x.MemberGroup.GroupName,
            MemberGroupId = x.MemberGroup.Id,
            SubGroupCode = x.SubGroupCode,
            StartDate = specificationValues[x.Id].StartDate,
            EndDate = specificationValues[x.Id].EndDate
        }).ToList();

        var json = _jsonHelper.FormatContractDetailsJsonData(rows, page, jsonData);

        return json;

在尝试为此方法编写单元测试时,我无法获得

_jsonHelper.FormatContractDetailsJsonData(rows, page, jsonData);

返回除null之外的任何内容。

这是我对方法的单元测试。

    [Test]
    public void GetMemberSubGroupsSpecifications_ReturnsJson()
    {
        //Arrange
        var jsonHelper = MockRepository.GenerateMock<IJsonHelper>();
        jsonHelper.Stub(x => x.FormatContractDetailsJsonData(Arg<int>.Is.Anything, Arg<int>.Is.Anything, Arg<List<object>>.Is.Anything)).Return(new JsonResult() { });

        var specificationType = MockRepository.GenerateMock<SpecificationType>();
        specificationType.Id = 2;

        var versionSpecification = MockRepository.GenerateMock<VersionSpecification>();
        versionSpecification.SpecificationType = specificationType;
        versionSpecification.Value = 2;

        var sessionAccessor = MockRepository.GenerateMock<ISessionAccessor>();

        var memberGroup = MockRepository.GenerateMock<MemberGroup>();
        memberGroup.GroupName = "groupName";
        memberGroup.Id = 2;
        var memberGroups = new List<MemberGroup>()
        {
            memberGroup
        };

        var contractVersion = MockRepository.GenerateMock<ContractVersion>();
        contractVersion.VersionSpecifications = new List<VersionSpecification>()
        {
            versionSpecification
        };

        var memberSubGroup = MockRepository.GenerateMock<MemberSubGroup>();
        memberSubGroup.Id = 2;
        memberSubGroup.MemberGroup = memberGroup;
        memberSubGroup.SubGroupCode = "subGroupCode";

        var listMemberSubGroups = new List<MemberSubGroup>()
        {
            memberSubGroup
        };

        sessionAccessor.Stub(x => x.MemberGroups).Return(memberGroups);
        sessionAccessor.Stub(x => x.Contract).Return(contractVersion);
        sessionAccessor.Stub(x => x.MemberSubGroups).Return(listMemberSubGroups);

        var searchController = ObjectFactory.GetSearchController(sessionAccessor, null, null, jsonHelper);

        //Act
        var actual = searchController.GetMemberSubgroupSpecifications(1, 1);

        //Assert
        Assert.IsNotNull(actual);
        Assert.IsInstanceOf(typeof(JsonResult), actual);
    }

我几天来一直在努力解决这个问题,而且我无法找到任何可以帮助我进行任何搜索的内容。 此外,我对使用犀牛模拟和单元测试仍然相当新。

这是FormatContractDetailsToJson方法:

    public JsonResult FormatContractDetailsJsonData<T>(int rows, int page, List<T> data)
    {
        var totalPages = (int)Math.Ceiling(data.Count / (float)rows);

        JsonResult json = new JsonResult();

        json.Data = new
        {
            total = totalPages,
            page,
            records = data.Count,
            rows = data
        };

        json.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

        return json;
    }

我相信列表数据参数是发生这种情况的原因,但我不确定。

1 个答案:

答案 0 :(得分:0)

您的设置代码中的类型不匹配:

jsonHelper.Stub(x => x.FormatContractDetailsJsonData(
       Arg<int>.Is.Anything,
       Arg<int>.Is.Anything,
       Arg<List<object>>.Is.Anything))
   .Return(new JsonResult() { });

在您测试的代码中,第3个参数不是对象列表 - 它将是编译器生成的匿名类型实例的列表,您不进行任何设置。

换句话说,您的测试设置为:

FormatContractDetailsJsonData<object>

当你的实现或多或少地调用时:

FormatContractDetailsJsonData<<>f_AnonymousType...>
然而,有一个黑客。 如果您的测试与测试代码位于同一个程序集中,您可以通过简单地声明另一个具有属性且具有相同名称,类型和顺序的匿名类型来生成此类型的虚拟

var dummyList = Enumerable
    .Range(0, 1)
    .Select(x => new
    {
        Id = 1,
        MemberSubGroupName = "",
        MemberGroupName = "",
        MemberGroupId = 1,
        SubGroupCode = "",
        StartDate = DateTime.Now,
        EndDate = DateTime.Now,
    })
    .ToList();

然后设置你的模拟:

jsonHelper.Stub(x => x.FormatContractDetailsJsonData(1, 1, dummyList))
    .IgnoreArguments()
    .Return(new JsonResult() { });

不幸的是,如果不是这种情况(源自同一程序集的匿名类型),您很可能必须为jsonData创建单独的类型才能使您的匹配工作。