При написании модульного теста для проверки созданного исключения попытались использовать оба метода ниже, используя xUnit
- Assert.Throws (действие)
- Record.Exception (действие)
Ниже приведен код
public class Me : Entity, IAggregateRoot
{
public string Name {get; }
private List<Friend> friends;
public IReadonlyCollection<Friend> Friends => friends;
public Me(string name)
{
Name = name;
friends = new List<Friend>();
}
public void AddFriend(Friend friend)
{
if(friend.Type != "UnKnown")
friend.Add(friend);
else
throw new Exception("Cannot add a unknown friend.");
}
}
public class Friend
{
public string Name {get; }
public string Type {get; }
public Friend(string name, string type)
{
Name = name;
Type = type;
}
}
using System;
using MediatR;
using System.Collections.Generic;
public abstract class Entity
{
int? _requestedHashCode;
int _Id;
public virtual int Id
{
get
{
return _Id;
}
protected set
{
_Id = value;
}
}
private List<INotification> _domainEvents;
public IReadOnlyCollection<INotification> DomainEvents => _ domainEvents?.AsReadOnly();
public void AddDomainEvent(INotification eventItem)
{
_domainEvents = _domainEvents ?? new List<INotification>();
_domainEvents.Add(eventItem);
}
public void RemoveDomainEvent(INotification eventItem)
{
_domainEvents?.Remove(eventItem);
}
public void ClearDomainEvents()
{
_domainEvents?.Clear();
}
public bool IsTransient()
{
return this.Id == default(Int32);
}
public override bool Equals(object obj)
{
if (obj == null || !(obj is Entity))
return false;
if (Object.ReferenceEquals(this, obj))
return true;
if (this.GetType() != obj.GetType())
return false;
Entity item = (Entity)obj;
if (item.IsTransient() || this.IsTransient())
return false;
else
return item.Id == this.Id;
}
public override int GetHashCode()
{
if (!IsTransient())
{
if (!_requestedHashCode.HasValue)
_requestedHashCode = this.Id.GetHashCode() ^ 31;
return _requestedHashCode.Value;
}
else
return base.GetHashCode();
}
public static bool operator ==(Entity left, Entity right)
{
if (Object.Equals(left, null))
return (Object.Equals(right, null)) ? true : false;
else
return left.Equals(right);
}
public static bool operator !=(Entity left, Entity right)
{
return !(left == right);
}
}
public interface IAggregateRoot
{}//its empty
Тестовый пример 1: использование Assert.Throws
[Fact]
public void add_friend_business_rule_validation_throws_exception1()
{
var me = new Me("mady");
var friend = new Friend("johnDoe","UnKnown");
Assert.Throws<Exception>(() => me.AddFriend(friend));
}
Тестовый пример 2: использование Record.Exception
[Fact]
public void add_friend_business_rule_validation_throws_exception()
{
var me = new Me("mady");
var friend = new Friend("johnDoe","UnKnown");
var ex = Record.Exception(() => me.AddFriend(friend));
Assert.NotNull(ex);
Assert.IsType<Exception>(ex);
}
Я хотел бы написать пример модульного теста для проверки исключения для предоставленного кода. Я ожидаю, что код должен генерировать исключение при ошибке проверки при попытке добавить объект в коллекцию.
Проблема. Тестовые примеры здесь не проходят и не проходят. Выполнение останавливается на следующей строке.
throw new Exception("Cannot add a unknown friend.");
Это произойдет, если у вас нет блока try catch, чтобы его поймать. Я ожидаю, что xUnit Assert.Throws & Record.Exception перехватит исключение, но это не так.
Примечание. Предоставленный код очень близок к реальному коду, при этом имена сущностей отличаются и упрощены за счет удаления ненужного кода.
Я видел следующую документацию
РЕДАКТИРОВАТЬ: Во время выполнения тестов поведение xUnit Assert.Throws & Record.Exception соответствует ожидаемому.
Проблема связана с отладочными тестами.
Как уже упоминалось, тестовые примеры не терпят неудач и не проходят. Всякий раз, когда какая-либо строка кода вызывает исключение, ближайший блок catch должен перехватить исключение. У меня аналогичные ожидания от xUnit Assert.Throws и Record.Exception на основе документации и пользовательского опыта. Однако при отладке теста это не так.
Альтернативный и хорошо известный подход для демонстрации проблемы и ожидаемого поведения.
[Fact]
public void add_friend_business_rule_validation_throws_exception1()
{
var me = new Me("mady");
var friend = new Friend("johnDoe","UnKnown");
Exception expectedException = null;
try
{
me.AddFriend(friend); //exception thrown block
}
catch(Exception ex)//exception catched - control not stopped
{
expectedException = ex;
}
Assert.NotNull(expectedException);
Assert.IsType<Exception>(expectedException);
}
AddFriend
. Скорее всего, вы либо утверждаете, либо возвращаете неправильный тип исключения - person Nkosi   schedule 04.03.2019