首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >xUnit Assert.Throws和Record.Exception不捕获异常

xUnit Assert.Throws和Record.Exception不捕获异常
EN

Stack Overflow用户
提问于 2019-03-03 20:39:53
回答 1查看 5.5K关注 0票数 2

在编写单元测试用例以测试抛出的异常时,尝试使用以下两种方法使用xUnit

  1. Assert.Throws(行动)
  2. Record.Exception(行动)

以下是代码

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

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

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

我想编写一个单元测试用例来测试所提供的代码的异常。我的期望是,当试图向集合添加实体时,代码应该在验证失败时抛出异常。

问题:这里的测试用例没有失败,也没有通过。执行在下一行停止。

代码语言:javascript
运行
复制
  throw new Exception("Cannot add a unknown friend.");

这将发生在您没有尝试捕获块来捕获它时。我预计xUnit Assert.Throws & Record.Exception会捕捉到异常,但事实并非如此。

注意:提供的代码与实际代码非常接近,实体名称是不同的,通过删除不必要的代码来简化。

我看过以下文档

  1. xUnit-Record.Exception文档
  2. 使用XUnit-堆栈溢出问题断言异常

编辑:在我运行Tests.时, xUnit Assert.Throws & Record.Exception行为如出一辙

问题与调试测试有关.

如前所述,测试用例没有失败,也没有通过。每当任何代码行抛出异常时,最近的catch块都会捕获异常。基于文档和用户体验,我对xUnit Assert.Throws & Record.Exception也有类似的期望。但是,在调试测试时,情况并非如此。

一种替代和众所周知的方法来演示问题和行为的期望。

代码语言:javascript
运行
复制
[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);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-04 18:50:50

运行测试时, xUnit Assert.Throws & Record.Exception行为与预期相同。

问题与调试测试有关.

我能够通过从异常抛出的行中跳转来调试测试。在看到在行处停止的控件后,按F8或F5继续,然后执行测试。

代码语言:javascript
运行
复制
throw new Exception("Cannot add a unknown friend.");
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54973512

复制
相关文章

相似问题

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