C# 使用参数调用了Nunit-Check方法

C# 使用参数调用了Nunit-Check方法,c#,nunit,C#,Nunit,测试应该测试AddDebug方法是否正常工作。因此,如果用户名为空,它将自动将用户名设置为“Anononymus”。但是,我看不到该列表,因为它是私有的,因此检查函数是否正常工作的唯一方法是利用AddDebug方法调用Add方法的机会。我必须验证Add方法是使用“Anonymous”参数调用的 我只能使用Nunit,Mock现在对我来说不是可选的 private List<Log> Entries; public Logger() { Entries

测试应该测试AddDebug方法是否正常工作。因此,如果用户名为空,它将自动将用户名设置为“Anononymus”。但是,我看不到该列表,因为它是私有的,因此检查函数是否正常工作的唯一方法是利用AddDebug方法调用Add方法的机会。我必须验证Add方法是使用“Anonymous”参数调用的 我只能使用Nunit,Mock现在对我来说不是可选的

private List<Log> Entries;
    public Logger()
    {
        Entries = new List<Log>();
    }
    public void Add(string text, LogLevels level, DateTime timeStamp, string userName)
    {
        var Enitity = new Log();
        Enitity.Text = text;
        Enitity.Level = level;
        Enitity.TimeStamp = timeStamp;
        Enitity.UserName = userName;
        Add(Enitity);

    }
    public void Add(Log log)
    {
        if (!(log.TimeStamp > DateTime.Now))
        {
            Entries.Add(log);
        }
    }
    public void AddDebug(string text, string userName = null)
    {
        if (String.IsNullOrEmpty(userName) == true)
        {
            Add(text, LogLevels.Debug, DateTime.Now, "Anonymus");
        }
        else
        {
            Add(text, LogLevels.Debug, DateTime.Now, userName);
        }

    }
私有列表条目;
公共记录器()
{
条目=新列表();
}
public void Add(字符串文本、日志级别、日期时间戳、字符串用户名)
{
var Enitity=新日志();
entity.Text=文本;
Enitity.Level=级别;
Enitity.TimeStamp=时间戳;
entity.UserName=用户名;
添加(Enitity);
}
公共作废添加(日志)
{
如果(!(log.TimeStamp>DateTime.Now))
{
条目。添加(日志);
}
}
public void AddDebug(字符串文本,字符串用户名=null)
{
if(String.IsNullOrEmpty(userName)==true)
{
添加(text,LogLevels.Debug,DateTime.Now,“匿名”);
}
其他的
{
添加(文本、LogLevels.Debug、DateTime.Now、用户名);
}
}

我建议您使用Moq这样的模拟框架。 请参阅我随附的示例代码。 ILog是日志类的接口

公共接口ILog{
作废添加(日志);
}
您的记录器类可能如下所示:

公共类记录器:ILog{
....
公共作废添加(日志)
{
如果(!(log.TimeStamp>DateTime.Now))
{
条目。添加(日志);
}
}
}
...
您可以这样设计您的测试用例

using Moq;

public class TestLogger 
{
  private Mock<ILog> _logMock;
  private ILog _logger;


  [Setup]
  public void SetUp()
  {

  _logMock = new Mock<ILog>();
  _logMock.Setup(a => a.Add(It.IsAny<Log>())).Verifiable(); // check if method is called

  _logger = _logMock.Object;          
  }

...

  [Test]
  public void SomeTest()
  {
   //test some business logik - inject your logger instance into businesslogic class

   //check if logger was called once
  _logMock.Verify(a => a.Add(It.IsAny<Log>()), Times.Once); 
  }

}


我建议您使用Moq这样的模拟框架。 请参阅我随附的示例代码。 ILog是日志类的接口

公共接口ILog{
作废添加(日志);
}
您的记录器类可能如下所示:

公共类记录器:ILog{
....
公共作废添加(日志)
{
如果(!(log.TimeStamp>DateTime.Now))
{
条目。添加(日志);
}
}
}
...
您可以这样设计您的测试用例

using Moq;

public class TestLogger 
{
  private Mock<ILog> _logMock;
  private ILog _logger;


  [Setup]
  public void SetUp()
  {

  _logMock = new Mock<ILog>();
  _logMock.Setup(a => a.Add(It.IsAny<Log>())).Verifiable(); // check if method is called

  _logger = _logMock.Object;          
  }

...

  [Test]
  public void SomeTest()
  {
   //test some business logik - inject your logger instance into businesslogic class

   //check if logger was called once
  _logMock.Verify(a => a.Add(It.IsAny<Log>()), Times.Once); 
  }

}

鉴于事实:

  • 您不能编辑单元测试不友好的
    记录器
  • 该实现不会将
    条目
    公开为公共信息,也不能将其作为参数传递到
    记录器
  • 这些方法都不是虚拟的
您必须使用反射来获取
条目

var logger = new Logger();
logger.AddDebug("some text", userName: null);

// Get Entries in logger
var entriesField = typeof(Logger).GetField(
    "Entries", BindingFlags.NonPublic | BindingFlags.Instance);
var entries = (List<Log>)entriesField.GetValue(logger);
var containsAnonymous = entries.Any(e => e.UserName == "Anonymus");
var记录器=新记录器();
AddDebug(“一些文本”,用户名:null);
//在记录器中获取条目
var entriesField=typeof(Logger).GetField(
“条目”,BindingFlags.NonPublic | BindingFlags.Instance);
var条目=(列表)entriesField.GetValue(记录器);
var containsAnonymous=entries.Any(e=>e.UserName==“匿名”);
然而,在单元测试中,这通常/可以说不是一个好的实践,因为这依赖于
Logger
类的内部结构,并且如果您更改
Logger
的实现,则此单元测试可能会中断

如果可能的话,我仍然建议使用@user8606929的解决方案之一。

鉴于以下事实:

  • 您不能编辑单元测试不友好的
    记录器
  • 该实现不会将
    条目
    公开为公共信息,也不能将其作为参数传递到
    记录器
  • 这些方法都不是虚拟的
您必须使用反射来获取
条目

var logger = new Logger();
logger.AddDebug("some text", userName: null);

// Get Entries in logger
var entriesField = typeof(Logger).GetField(
    "Entries", BindingFlags.NonPublic | BindingFlags.Instance);
var entries = (List<Log>)entriesField.GetValue(logger);
var containsAnonymous = entries.Any(e => e.UserName == "Anonymus");
var记录器=新记录器();
AddDebug(“一些文本”,用户名:null);
//在记录器中获取条目
var entriesField=typeof(Logger).GetField(
“条目”,BindingFlags.NonPublic | BindingFlags.Instance);
var条目=(列表)entriesField.GetValue(记录器);
var containsAnonymous=entries.Any(e=>e.UserName==“匿名”);
然而,在单元测试中,这通常/可以说不是一个好的实践,因为这依赖于
Logger
类的内部结构,并且如果您更改
Logger
的实现,则此单元测试可能会中断


如果可能的话,我仍然建议使用@user8606929的解决方案之一。

您可以为您的方法使用
Moq
library ti setup mock,并验证它是否被调用,但它需要使用接口这个类做什么?只需将日志保存到私有成员,而其他方法不使用这些日志,就可以使该类变得无用。这个类是如何实际使用的,是否有一些方法使用
条目
列表?您可以使用
Moq
library ti为您的方法设置mock,并验证它是否被调用,但它需要使用接口这个类做什么?只需将日志保存到私有成员,而其他方法不使用这些日志,就可以使该类变得无用。这个类实际上是如何使用的,是否有一些方法使用
条目
列表?谢谢!我只能使用Nunit,因为我们还没有学习和模仿,这将是我家庭作业的一部分。如果它解决了你的问题,如果你能将我的答案标记为“接受答案”,我会很高兴。如果没有,请给我更多关于您的问题和限制的信息。祝您有美好的一天,并祝您编码/学习愉快!问题是我不能添加接口之类的附加内容,因为方法、类等都是给定的。Mock对我来说不是可选的。所以我的任务是为这些方法编写Nunit测试。我也有一个BL.Test类,在那里我可以写测试。我在上面编辑了我的答案,请检查这是否能解决你的问题,可惜它没有解决。测试应该测试AddDebug方法是否正常工作。因此,如果用户名为空,它将自动将用户名设置为“Anononymus”。但是我看不到这个列表