使用Moq和Xunit测试接口

时间:2017-08-18 06:20:46

标签: c# unit-testing moq xunit

我是XUnit和Moq的新手。我试图了解测试框架和准备单元测试用例。我正在使用依赖注入来注入接口。

我正在测试以下接口

using System.Collections.Generic;
using Zeiss.IMT.MCCNeo.Settings.Entities;

namespace Zeiss.IMT.MCCNeo.Settings.Data.Interface
{
    public interface IProfilesRepository
    {
        IList<Profile> GetAllProfiles();
        IList<Profile> GetProfilesMatchingUserID(string userid);
        IList<Profile> GetProfilesForUserIDWithSettingName(string userid, string settingname);
    }
}

实施类

using System;
using System.Collections.Generic;
using Zeiss.IMT.MCCNeo.Settings.Data.Interface;
using Zeiss.IMT.MCCNeo.Settings.Entities;
using System.Linq;
using Zeiss.IMT.MCCNeo.Settings.Data.Singleton;
using Zeiss.IMT.MCCNeo.Settings.Utilities;

namespace Zeiss.IMT.MCCNeo.Settings.Data.Repository
{
    public class ProfilesRepository : IProfilesRepository
    {
        private IProfileDataRepository _profileDataRepository { get; set; }
        public ProfilesRepository(IProfileDataRepository ProfileDataRepository)
        {
            _profileDataRepository = ProfileDataRepository;

        }
        public IList<Profile> GetAllProfiles()
        {
            return _profileDataRepository.Get();
        }
        public IList<Profile> GetProfilesMatchingUserID(string userid)
        {
            if (string.IsNullOrWhiteSpace(userid)) throw new ArgumentException("User Id Cannot be null");
            return _profileDataRepository.Get().Where(puid => puid.UserID.ToLower() == userid.ToLower()).ToList<Profile>();
        }
        public IList<Profile> GetProfilesForUserIDWithSettingName(string userid, string settingname)
        {
            if (string.IsNullOrWhiteSpace(userid) || string.IsNullOrWhiteSpace(settingname)) throw new ArgumentException("User Id or settingname Cannot be null");
            var profilesWithSettings = _profileDataRepository.Get().Where(p => p.UserID.ToLower() == userid.ToLower() & p.Settings.Any(s => s.Name.ToLower() == settingname.ToLower()));
            return profilesWithSettings.ToList();
        }
    }
}

处理数据加载和数据保存到文件的数据存储库

using System;
using System.Collections.Generic;
using Zeiss.IMT.MCCNeo.Settings.Entities;

namespace Zeiss.IMT.MCCNeo.Settings.Data.Singleton
{
    public interface IProfileDataRepository
    {
        List<Profile> Get();

        List<Profile> Get(Func<Profile, bool> filter);
        void Save(List<Profile> profilesToSave);
    }
}

using System;
using System.Collections.Generic;
using Zeiss.IMT.MCCNeo.Settings.Entities;
using Zeiss.IMT.MCCNeo.Settings.Utilities;
using System.Linq;
namespace Zeiss.IMT.MCCNeo.Settings.Data.Singleton
{
    public class ProfileDataRepository : IProfileDataRepository
    {
        private static List<Profile> profiles;
        public IRepository _repository { get; set; }
        public ProfileDataRepository(IRepository repository)
        {
            _repository = repository;
            if (profiles == null)
            {
                profiles = repository.Get<Profile>();
            }
        }

        public List<Profile> Get()
        {
            return profiles;
        }

        public List<Profile> Get(Func<Profile, bool> filter)
        {
            return profiles.Where(filter).ToList();
        }

        public void Save(List<Profile> profilesToSave)
        {
            profiles = profilesToSave;
            _repository.Save<List<Profile>>(profiles);
        }
    }
}

我正在尝试模拟Profile实体,然后将其传递给模拟接口。但是,我仍然缺乏对如何模拟接口和传递数据实体的理解。

Entity class

    namespace Zeiss.IMT.MCCNeo.Settings.Entities
    {
        public class Profile
        {
            public string UserID { get; set; }
            public string UserName { get; set; }
            public List<Setting> Settings { get; set; }
        }
    }

Test class

    using Moq;
using System;
using System.Collections.Generic;
using System.Text;
using Zeiss.IMT.MCCNeo.Settings.Data.Interface;
using Zeiss.IMT.MCCNeo.Settings.Data.Singleton;
using Zeiss.IMT.MCCNeo.Settings.Entities;

namespace Zeiss.IMT.MCCNeo.Settings.Tests
{
    public class ProfilesServiceTests
    {
        private readonly Mock<IProfileDataRepository> ProfileDataProvider;
        private readonly Mock<IProfilesRepository> ProfilesProvider;

        public ProfilesServiceTests()
        {
            ProfileDataProvider = new Mock<IProfileDataRepository>();
            ProfilesProvider = new Mock<IProfilesRepository>();
        }

        public void GetProfilesMatchingUserID_WhenPassedNull_Return_Exception()
        {

            List<Setting> settings = new List<Setting>() {
                new Setting(){
                    Name = "RefreshInterval",
                     Value = { },
                     Type = "string",
                Encrypted = true,
                ReadOnly = true,
                CreatedOn = new DateTime(),
                ModifiedOn = new DateTime(),
                Valid = true,
                Enabled = true,
                Description = "Protocol Archive view renwal interval in seconds. Minimum value = 300 Maximum value = 28800"
                }
            };

            Profile profile = new Profile()
            {
                UserID = "admin",
                UserName = "admin",
                Settings = settings
            };

            List<Profile> profiles = new List<Profile>()
            {
                profile
            };

            ProfileDataProvider.Setup(x => x.Get()).Returns(profiles);
            ProfilesProvider.Setup(x => x.GetProfilesMatchingUserID(null)).Returns(new NullReferenceException());

        }
    }
}

请建议。

1 个答案:

答案 0 :(得分:3)

感觉就像你想要在一个班级中测试它(或很多)。请记住,您还不需要进行集成测试。

首先看看你的Select C.customer_id, C.order_id, C.city, From (select * from (query_1 ) as A join (query_2 ) as B on A.customer_id = B.customer_id) C

我们需要像

这样的东西
ProfilesRepository

这并不能完成所有测试,但会让您了解如何继续。 请记住,分离所有类/单元测试等。每个测试应检查一个例外。请记住,单元测试只测试一件事,一种情况。如果您的代码抛出了两个不同的例外情况,则它们无法在相同条件下执行此操作。

祝你好运!