这是我的BLL服务,它与县合作:
public class CountryBLLService : ICountryBLL
{
private readonly ITimeSheetContext _context;
public CountryBLLService(ITimeSheetContext context)
{
_context = context;
}
public void CreateCountry(Country country)
{
_context.Countries.Create(country);
}
public Country GetCountry(Guid id)
{
return _context.Countries.Read(id);
}
public bool RemoveCountry(Guid id)
{
return _context.Countries.Delet(id);
}
public void UpdateCountry(Country country)
{
_context.Countries.Update(country);
}
}
这是一个TimeSheetContext:
public class TimeSeetContext : ITimeSheetContext
{
public ICountryRepository Countries { get; private set; }
public TimeSeetContext()
{
Countries = new CountryRepository();
}
}
所以,我想使用模拟TimeSheetContext来UnitTest throwException CountryBLL服务。但是我得到错误:像.Received()这样的NSubstitute扩展方法只能在使用Substitute.For()和相关方法创建的对象上调用。
这是我悲伤的尝试:
[TestClass]
public class CountryTestBLL
{
ICountryBLL countrybLL;
ITimeSheetContext context;
[TestInitialize]
public void Initialize()
{
context = Substitute.For<ITimeSheetContext>();
countrybLL = new CountryBLLService(context);
}
[TestMethod]
[ExpectedException(typeof(Exception),"Country Alreday exist")]
public void CreateContry_throwEx()
{
countrybLL
.When(x => x.CreateCountry(new Country()))
.Do(x => { throw new Exception(); });
countrybLL.CreateCountry(new Country());
}
}
欢迎来到StackOverflow! NSubstitute仅适用于您使用Substitute.For<T>
创建的实例。所以你可以使用When..Do
,Returns
,Received
等与context
(使用NSubstitute创建),但不能使用countrybLL
(使用new CountryBLLService
创建)。
尝试通过context
嘲笑:
[TestMethod]
[ExpectedException(typeof(Exception),"Country Alreday exist")]
public void CreateContry_throwEx()
{
var existingCountry = new Country();
context.Countries
.When(x => x.CreateCountry(existingCountry))
.Do(x => { throw new Exception(); });
// Or context.Contries.CreateCountry(...).Returns(...) for non-void member
countrybLL.CreateCountry(existingCountry);
}
顺便说一句,当我在我的测试中遇到这样的问题时,我发现有时不使用模拟框架,而是手动创建我的类正在使用的依赖项的替代。这就是NSubstitute和其他模拟库自动为我们做的事情,但它可以帮助突出我正在测试的内容以及我为我的测试做什么。
例如:
class CountryExistsRepository : ICountryRepository {
public void CreateCountry(Country c) {
throw new Exception("country already exists");
}
// ... other members omitted ...
}
[TestMethod]
[ExpectedException(typeof(Exception),"Country already exist")]
public void CreateContry_throwEx()
{
var existingCountry = new Country();
var countrybLL = new CountryBLLService(
new TimeSeetContext(new CountryExistsRepository()));
countrybLL.CreateCountry(existingCountry);
}
我发现这使我更清楚我正在使用的真实代码,与我为测试所伪装的相比。然后,一旦我厌倦了手动实现这些案例,我就切换到一个模拟库来为我做。在这种情况下,它表明我们可能不需要替换TimeSeetContext
,仅用于底层的ICountryRepository
。
希望这可以帮助。