可能的回购模式问题或如何从多个模拟实例创建一个模拟实例?
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> {
//...
}
以及其他存储库 IARepository
和 IBRepository
.
的类似内容
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 的其他成员执行相同的模式。
我想测试需要三个不同接口的逻辑。我怎样才能将这些结合起来,因为当我有三个实例时我不能使用模拟方法。我想我对存储库做了一些非常错误的事情,但我不知道。感谢您的帮助!
[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> {
//...
}
以及其他存储库 IARepository
和 IBRepository
.
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 的其他成员执行相同的模式。