nЗаменимое насмешливое исключение - PullRequest
0 голосов
/ 13 сентября 2018

Вот мой сервис 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();
    }
}

Итак, я хочу использовать сервис UnitTest throwException CountryBLL, используя фиктивный TimeSheetContext.Но я получаю ошибку: методы расширения NSubstitute, такие как .Received (), могут быть вызваны только для объектов, созданных с использованием 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());


    }
}

1 Ответ

0 голосов
/ 14 сентября 2018

Добро пожаловать в 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.

Надеюсь, это поможет.

...