MOQ返回null.[模拟具体类方法]

Tij*_*ohn 0 generics inheritance unit-testing moq mocking

[使用Moq]

我试图模拟一个具体的类并模拟该类的虚拟方法"Get()".在测试方法"GetItemsNotNull()"时,我总是返回null,而不是返回模拟函数.

这是代码


//SomeClasses.cs
namespace MoQExamples
{
    public abstract class Entity
    {

    }

    public class Abc : Entity
    {

    }

    public interface IRepository<T> where T : Entity
    {
        IQueryable<T> Get();
    }

    public class Repository<T> : IRepository<T> where T : Entity
    {
        private readonly ISession _session;

        public Repository()
        {
            _session = null;
        }

        public Repository(ISession session)
        {
            _session = session;
        }

        protected ISession CurrentSession
        {
            get { return _session; }
        }

        public virtual IQueryable<T> Get()
        {
            return CurrentSession.Query<T>();
        }

    }

    public interface IAbcRepository
    {
        Abc GetItemsNotNull();
    }

    public class AbcRepository : Repository<Abc>, IAbcRepository
    {
        public Abc GetItemsNotNull()
        {
            return Get().FirstOrDefault(abc => abc !=null);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是测试类

namespace MoQExamples
{
    [TestFixture]
    public class SomeClassesTest
    {
        private readonly Mock<AbcRepository> _abcRepositoryMock = new Mock<AbcRepository>(MockBehavior.Strict) { CallBase = true };

        [SetUp]
        public void SetupTest()
        {
            _abcRepositoryMock.Setup(x => x.Get()).Returns(Get);
        }

        public IQueryable<Abc> Get()
        {
            return (new List<Abc>() { new Abc() }) as IQueryable<Abc>;
        }

        [Test]
        public void TestGetItemsNotNull()
        {
            Assert.IsNotNull(_abcRepositoryMock.Object.GetItemsNotNull());
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

断言alays失败..而不是返回SomeClassesTest.Get()

感谢先进的家伙们!

Jon*_*eet 7

我怀疑这是问题所在:

return (new List<Abc>() { new Abc() }) as IQueryable<Abc>;
Run Code Online (Sandbox Code Playgroud)

List<T>没有实现IQueryable<T>,所以这将始终返回null.打电话AsQueryable转换它:

return new List<Abc>().AsQueryable();
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这是as在大多数情况下偏好强制转换的一个原因:如果你只是强制转换IQueryable<Abc>,你就会在线路上收到异常,这确实导致了问题.只有as当它不是转换为"失败" 的错误时才应该使用.一个as运营商应该几乎总是跟一个无效的测试.

(注意,这种行为本身与模拟或Moq无关.它只是as运算符的行为...)