我是TDD开发的新手,我刚开始用Nunit 3.7.1,Newtonsoft.Json版本= 10.0.3,JustMock Lite版本2016.2.426.1,C#和.NET进行一些测试框架4.7。
我想测试这个课程:
public class LoadFinishedTrzlBatch
{
private IGenericRepository<ProductionOrder> proOrdRepository;
private IGenericRepository<Batch> batchRepository;
private IGenericRepository<Code> codeRepository;
private IGenericRepository<Aggregation> aggregationRepository;
private IGenericRepository<AggregationChildren> aggChildrenRepository;
public LoadFinishedTrzlBatch(
IGenericRepository<ProductionOrder> proOrdRepository,
IGenericRepository<Batch> batchRepository,
IGenericRepository<Code> codeRepository,
IGenericRepository<Aggregation> aggregationRepository,
IGenericRepository<AggregationChildren> aggChildrenRepository)
{
this.proOrdRepository = proOrdRepository;
this.batchRepository = batchRepository;
this.codeRepository = codeRepository;
this.aggregationRepository = aggregationRepository;
this.aggChildrenRepository = aggChildrenRepository;
}
public bool ExistsProductionOrder(string productionOrderName)
{
if (string.IsNullOrWhiteSpace(productionOrderName))
throw new ArgumentNullException(nameof(productionOrderName));
return (
proOrdRepository
.SearchFor(p => p.Name == productionOrderName)
.FirstOrDefault() != null
);
}
}
通过这个测试:
[TestFixture]
class LoadFinishedTrzlBatchTest
{
private LoadFinishedTrzlBatch _load;
[SetUp]
public void SetUpLoadFinishedTrzlBatch()
{
var proOrdRepository =
Mock.Create<IGenericRepository<ProductionOrder>>();
var batchRepository =
Mock.Create<IGenericRepository<Batch>>();
var codeRepository =
Mock.Create<IGenericRepository<Code>>();
var aggRepository =
Mock.Create<IGenericRepository<Aggregation>>();
var aggChildrenRepository =
Mock.Create<IGenericRepository<AggregationChildren>>();
_load = new LoadFinishedTrzlBatch(
proOrdRepository,
batchRepository,
codeRepository,
aggRepository,
aggChildrenRepository);
}
[Test]
public void ShouldExistsProductionOrder()
{
// Arrange
Mock.Arrange(() => _load.ExistsProductionOrder("ProOrd"))
.Returns(true)
.MustBeCalled();
// Act
var actual = _load.ExistsProductionOrder("ProOrd");
// Assert
Assert.AreEqual(actual, true);
}
}
最后这是IGenericRepository
:
public interface IGenericRepository<TEntity>
{
[ OMITTED ]
IQueryable<TEntity> SearchFor(Expression<Func<TEntity, bool>> predicate);
[ OMITTED ]
}
首先,我不确定这是否是测试方法LoadFinishedTrzlBatch.ExistsProductionOrder
的正确方法。对于TDD而言,一切都是新的,我迷失了。
我对如何模仿IGenericRepository<ProductionOrder>
感到困惑。它始终是真的,我没有测试IGenericRepository<ProductionOrder>
。也许是因为我没有测试存储库。
我在学习,但我不知道自己在做什么。这就是我提出这个问题的原因。我想测试ExistsProductionOrder
方法。
如何测试ExistsProductionOrder
方法?
答案 0 :(得分:1)
实际上,如果方法ExistsProductionOrder
做了它应该做的事情,你想要测试。因此你不应该模仿它。但是,您希望模拟在 方法中名为的成员,例如对IGenericRepository<T>.DoSomething()
的任何调用。
然而,只需调用它并将其结果与您期望的结果进行比较:
[Test]
public void ShouldExistsProductionOrder()
{
// Act
var actual = _load.ExistsProductionOrder("ProOrd");
Assert.IsTrue(actual);
}
现在你的方法看起来像这样:
bool ExistsProductionOrder() {
this.proOrdRepository.DoSomething();
return ...
}
你可以将对 DoSomething
的调用替换为不同的东西 - 你的模拟。
答案 1 :(得分:1)
You need to separate the target dependency so that it can be arranged in isolation in the test case. You also do no mock the SUT (Subject under test). You mock its dependencies. In this case you want to mock the generic repository and arrange the method being called. ie SearchFor
Assuming that method takes a expression predicate, you can arrange the mock to expect one and then apply it to a fake collection store to mock an actual data store.
[TestFixture]
public class LoadFinishedTrzlBatchTest {
private LoadFinishedTrzlBatch sut;
//need this later so declaring as field.
private IGenericRepository<ProductionOrder> proOrdRepository;
[SetUp]
public void SetUpLoadFinishedTrzlBatch() {
//Not using these so they can be declared locally
var batchRepository =
Mock.Create<IGenericRepository<Batch>>();
var codeRepository =
Mock.Create<IGenericRepository<Code>>();
var aggRepository =
Mock.Create<IGenericRepository<Aggregation>>();
var aggChildrenRepository =
Mock.Create<IGenericRepository<AggregationChildren>>();
//initializing target mock
proOrdRepository =
Mock.Create<IGenericRepository<ProductionOrder>>();
sut = new LoadFinishedTrzlBatch(
proOrdRepository,
batchRepository,
codeRepository,
aggRepository,
aggChildrenRepository);
}
[Test]
public void ShouldExistsProductionOrder()
{
// Arrange
var productionOrderName = "ProOrd";
var orders = new List<ProductionOrder>() {
new ProductionOrder { Name = productionOrderName },
new ProductionOrder { Name = "Dummy for Filter" }
};
Mock.Arrange(() => proOrdRepository
.SearchFor(Arg.IsAny<Expression<Func<ProductionOrder,bool>>>()))
.Returns((Expression<Func<ProductionOrder,bool>> expression) =>
orders.Where(expression.Compile()).AsQueryable()
)
.MustBeCalled();
// Act
var actual = sut.ExistsProductionOrder(productionOrderName);
// Assert
Assert.IsTrue(actual);
}
}