通过 machine.fakes 模拟多个接口
mocking multiple interfaces wirth machine.fakes
如何获得
的等价物
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(随便);
这是一个 class,用最少的代码重现了这个问题。
您需要为 Entity Framework、Machine.Specifications、Machie.Specifications.Should、Machine.Fakes、Machine.Fakes.NSubstitute、NSubstitute(或任何其他模拟框架插件)添加包
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);
};
}
}
}
无法通过 Machine.Fakes 在一个伪造中伪造多个接口 - 相当于 NSubstitute 的 Substitute.For<>()
。
我看到两个选项供您选择:
直接使用 NSubstitute。
你总是可以做
Subject = Substitute.For<DbSet<TestClass>, IQueryable<TestClass>>();
而不是
Subject = An<DbSet<TestClass>>();
缺点是您放弃了对底层模拟框架的独立性和 Machine.Fake 的自动模拟功能
重构您的代码,一次只伪造一个接口。这是我的首选。
我的第一次尝试是伪造 IDbSet<>
而不是 DbSet<>
并且只针对这个接口工作。但是,我对您要实现的目标知之甚少,无法提供更详细的提示。作为一般规则,您应该始终尝试依赖接口。也许你可以让被测的 class 独立于具体的 DbSet<>
?
如何获得
的等价物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(随便);
这是一个 class,用最少的代码重现了这个问题。 您需要为 Entity Framework、Machine.Specifications、Machie.Specifications.Should、Machine.Fakes、Machine.Fakes.NSubstitute、NSubstitute(或任何其他模拟框架插件)添加包
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);
};
}
}
}
无法通过 Machine.Fakes 在一个伪造中伪造多个接口 - 相当于 NSubstitute 的 Substitute.For<>()
。
我看到两个选项供您选择:
直接使用 NSubstitute。
你总是可以做
Subject = Substitute.For<DbSet<TestClass>, IQueryable<TestClass>>();
而不是
Subject = An<DbSet<TestClass>>();
缺点是您放弃了对底层模拟框架的独立性和 Machine.Fake 的自动模拟功能重构您的代码,一次只伪造一个接口。这是我的首选。
我的第一次尝试是伪造IDbSet<>
而不是DbSet<>
并且只针对这个接口工作。但是,我对您要实现的目标知之甚少,无法提供更详细的提示。作为一般规则,您应该始终尝试依赖接口。也许你可以让被测的 class 独立于具体的DbSet<>
?