0

我怎样才能获得相当于

Substitute.For<DbSet<MyClass>, IQueryable<MyClass>, IDbAsyncEnumerable>()

用 machine.fakes?我尝试使用

var myFake = An<DbSet<MyClass>>();
myFake.WhenToldTo(m => ((IQueryable<MyClass>)m).Provider).Return(whatever);

但我得到以下 NotImplementedException:

The member 'IQueryable.Provider' has not been implemented on type 'DbSet`1Proxy' which 
inherits from 'DbSet`1'. Test doubles for 'DbSet`1' must provide implementations of 
methods and properties that are used.

myFake.WhenToldTo(m => ((IQueryable)m).Provider).Return(whatever); 引发相同的异常。

这是一个用最少的代码重现问题的类。您需要为实体框架、Machine.Specifications、Machie.Specifications.Should、Machine.Fakes、Machine.Fakes.NSubstitute、NSubstitute(或任何其他 Mock Framework 插件)添加包

using System.Data.Entity;
using System.Linq;
using Machine.Fakes;
using Machine.Specifications;

namespace SpecsTests
{
    public class TestClass
    {}

    [Subject("Test")]
    internal class TestSpecifications
    {
        [Subject("Test")]
        private class Test : WithFakes
        {
            private static int Count;
            private static DbSet<TestClass> Subject;

            private Establish context = () =>
                                        {
                                            var data = new [] { new TestClass() }.AsQueryable();
                                            Subject = An<DbSet<TestClass>>();

                                            Subject.WhenToldTo(m => ((IQueryable)m).Provider).Return( data.Provider);
                                        };

            private Because of = () => { Count = Subject.Count(); };

            private It Should_return_expected_results = () =>
                                                        {
                                                            Count.ShouldEqual(1);
                                                        };

        }
    }
}
4

1 回答 1

1

没有办法用 Machine.Fakes 伪造一个以上的接口 - 相当于 NSubstitute 的Substitute.For<>()。我看到你有两个选择:

  1. 直接使用 NSubstitute。
    你总是可以做
    Subject = Substitute.For<DbSet<TestClass>, IQueryable<TestClass>>();
    而不是
    Subject = An<DbSet<TestClass>>();
    缺点是你放弃了对底层模拟框架和 Machine.Fake 的自动模拟能力的独立性

  2. 重构你的代码,一次只伪造一个接口。这将是我的首选。
    我的第一次尝试是伪造IDbSet<>而不是DbSet<>只针对这个界面工作。但是,我对您要达到的目标知之甚少,无法提供更详细的提示。作为一般规则,您应该始终尝试依赖接口。也许你可以让被测试的类独立于具体的DbSet<>

于 2015-01-20T08:40:29.010 回答