可能的回购模式问题或如何从多个模拟实例创建一个模拟实例?

Possible repo pattern question or how to create one mock instance form multiple mock instances?

我想测试需要三个不同接口的逻辑。我怎样才能将这些结合起来,因为当我有三个实例时我不能使用模拟方法。我想我对存储库做了一些非常错误的事情,但我不知道。感谢您的帮助!

    [Test]
    public void TestThatLogicABCWorks()
    {
        Mock<IRepositoryA> mockInstance1 = new Mock<IRepositoryA>();
        Mock<IRepositoryB> mockInstance2 = new Mock<IRepositoryB>();
        Mock<IRepositoryC> mockInstance3 = new Mock<IRepositoryC>();
        LogicABC logic = new LogicABC(mockInstance1.Object, mockInstance2.Object, mockInstance3.Object);
    }

编辑:我有三个实体 类、1 个通用存储库和三个实体特定存储库。在逻辑上,我进行的查询包括所有三个实体,我将其作为:

public class LogicABC : ILogic
{

    IRepository<A> ARepo; //generic repo
    IRepository<B> BRepo;
    IRepository<C> CRepo;

    public LogicABC(IARepository ARepo, IBRepository BRepo, ICRepository CRepo)
    {
        this.ARepo = ARepo; //entity specific repos
        this.BRepo = BRepo;
        this.CRepo = CRepo;
    }

    public LogicABC()
    {
        var Entity = new ABCEntities(); //context
        this.ARepo = new ARepository(Entity);
        this.BRepo = new BRepository(Entity);
        this.CRepo = new CRepository(Entity);
    }
    //queries
    public List<int> Query1()
    {
    var q1 = from x in CRepo.GetAll()
             select x.Id;
    return q1.ToList();
    }

我需要用 mock 测试这些查询。例如设置 logicABC.Query1() returns 1 然后验证它。

您需要在每个存储库模拟中模拟方法,即在 mockInstance1、mockInstance2 和 mockInstance3 中。在此之后,您将能够通过检查每个 repos

的应用模拟来验证 LogicABC 内部的行为

更新:

您的测试应如下所示:

[Test]
public void TestThatLogicABCWorks()
{
    Mock<IRepositoryA> mockInstance1 = new Mock<IRepositoryA>();
    mockInstance1.Setup(foo => foo.Do()).Returns(() => 1);

    Mock<IRepositoryB> mockInstance2 = new Mock<IRepositoryB>();
    mockInstance2.Setup(boo => boo.Do2()).Returns(() => 2);

    Mock<IRepositoryC> mockInstance3 = new Mock<IRepositoryC>();
    mockInstance3.Setup(doo => doo.Do3()).Returns(() => 3);

    LogicABC logic = new LogicABC(mockInstance1.Object, mockInstance2.Object, mockInstance3.Object);

    logic.DoLogic();

    // do some asserts here
}

在测试具有依赖关系的被测对象时,应提供测试流程完成所明确需要的依赖关系。

在这种情况下 Query1() 仅使用 ICRepository 并且未显示与其他两个依赖项的任何交互。如果确实如此,则不需要其他依赖项。

根据被测方法,做出以下假设

public interface ICRepository : IRepository<C> {
    //...
}

以及其他存储库 IARepositoryIBRepository.

的类似内容
public interface IRemository<TEntity> {
    IEnumerable<TEntity> GetAll();

    //...other members
}

public class C {
    public int Id { get; set; }

    //...other members
}

所以 Query1 的测试可以按如下方式完成。

[Test]
public void LogicABC_Query1_Should_Return_One_Id() {
    //Arrange
    int expected = 123456789;
    var items = new [] { new C { Id = expectedId } }

    Mock<IRepositoryC> mock = new Mock<IRepositoryC>();
    mock.Setup(_ => _.GetAll()).Returns(items);

    LogicABC logic = new LogicABC(null, null, mock.Object);

    //Act
    List<int> list = logic.Query1();

    //Assert

    mock.Verify(_ => _.GetAll(), Times.Once());

    //checking expected behavior - using FluentAssertions
    list.Should().HaveCount(1);

    int actual = list.First();

    actual.Should().Be(expected); // using FluentAssertions
}

上面的单元测试测试了一个主题方法的预期行为。可以对被测 class 的其他成员执行相同的模式。