首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >nSubstitute模拟异常

nSubstitute模拟异常
EN

Stack Overflow用户
提问于 2018-09-13 19:15:36
回答 1查看 1.5K关注 0票数 1

这是我的BLL服务,与各县合作:

代码语言:javascript
复制
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:

代码语言:javascript
复制
 public class TimeSeetContext : ITimeSheetContext
{
    public ICountryRepository Countries { get; private set; }


    public TimeSeetContext()
    {
        Countries = new CountryRepository();
    }
}

因此,我希望UnitTest throwException CountryBLL服务使用模拟TimeSheetContext。但是im获取错误: NSubstitute扩展方法(如.Received() )只能对使用Substitute.For()和相关方法创建的对象调用。

下面是我悲伤的尝试:

代码语言:javascript
复制
[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());


    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-14 04:36:10

欢迎来到StackOverflow!NSubstitute只适用于使用Substitute.For<T>创建的实例。因此,您可以在When..DoReturnsReceived等与context (使用NSubstitute创建)一起使用,而不能使用countrybLL (使用new CountryBLLService创建)。

尝试通过context来嘲笑

代码语言:javascript
复制
[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和其他模拟库自动为我们所做的,但它可以帮助我们准确地突出我正在测试的内容和我为测试而伪造的内容。

例如:

代码语言:javascript
复制
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

希望这能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52320392

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档