dro*_*gon 4 c# nunit unit-testing moq
这是我要执行的操作的一个非常简单的示例:
public class Bar
{
public void SomeMethod(string param)
{
//whatever
}
}
public interface IBarRepository
{
List<Bar> GetBarsFromStore();
}
public class FooService
{
private readonly IBarRepository _barRepository;
public FooService(IBarRepository barRepository)
{
_barRepository = barRepository;
}
public List<Bar> GetBars()
{
var bars = _barRepository.GetBarsFromStore();
foreach (var bar in bars)
{
bar.SomeMethod("someValue");
}
return bars;
}
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中,我正在模拟IBarRepository以返回在单元测试中定义的具体List,并将该模拟的存储库实例传递给FooService构造函数。
我想在FooService方法GetBars中验证从存储库返回的每个Bar都调用了SomeMethod。我正在使用起订量。有什么方法可以在不嘲笑返回的Bars列表的情况下(即使可能的话)并且不必在Bar中放置一些hacky标志(yuck)?
我正在跟踪DDD书中的示例,但我开始认为它闻起来是因为我在测试实现方面遇到了挑战。
修订...通过:
public class Bar
{
public virtual void SomeMethod(string param)
{
//whatever
}
}
public interface IBarRepository
{
List<Bar> GetBarsFromStore();
}
public class FooService
{
private readonly IBarRepository _barRepository;
public FooService(IBarRepository barRepository)
{
_barRepository = barRepository;
}
public List<Bar> GetBars()
{
var bars = _barRepository.GetBarsFromStore();
foreach (var bar in bars)
{
bar.SomeMethod("someValue");
}
return bars;
}
}
[TestMethod]
public void Verify_All_Bars_Called()
{
var myBarStub = new Mock<Bar>();
var mySecondBarStub = new Mock<Bar>();
var myBarList = new List<Bar>() { myBarStub.Object, mySecondBarStub.Object };
var myStub = new Mock<IBarRepository>();
myStub.Setup(repos => repos.GetBarsFromStore()).Returns(myBarList);
var myService = new FooService(myStub.Object);
myService.GetBars();
myBarStub.Verify(bar => bar.SomeMethod(It.IsAny<string>()), Times.Once());
mySecondBarStub.Verify(bar => bar.SomeMethod(It.IsAny<string>()), Times.Once());
}
Run Code Online (Sandbox Code Playgroud)
请注意,对Bar类的更改很小(SomeMethod()是虚拟的)。更改,但不涉及标志... :)
现在,就更广泛的设计而言,您的工具栏上正在进行一些更改(无论“ SomeMethod()”实际上是做什么的)。最好的办法可能是验证此突变是否发生在从FooService.GetBars()返回的每个Bar上。也就是说,将您的存储库存根设置为返回一些小节,然后验证SomeMethod()所执行的任何更改都已发生。毕竟,您控制着将要返回的柱线,因此您可以设置它们的pre-SomeMethod()状态,然后检查其post-SomeMethod()状态。