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

Nunit -Check method was called with a parameter

测试应测试 AddDebug 方法是否正常工作。所以如果用户名是null 会自动设置用户名为"Anononymus"。但是我看不到列表,因为它是私有的,因此检查功能是否正常工作的唯一方法是利用 AddDebug 方法调用 Add 方法的机会。我必须验证是否使用 "Anonymous" 参数调用了 Add 方法 我只能使用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);
        }

    }

我建议您使用像 Moq 这样的模拟框架。 请参阅我附加的示例代码。 ILog 是 Log Class.

的接口
public interface ILog {
 void Add(Log log);
}

您的记录器 class 可能如下所示:

public class Logger : ILog{
....
public void Add(Log log)
   {
       if (!(log.TimeStamp > DateTime.Now))
        {
            Entries.Add(log);
        }
   }
}
...

你可以像这样设计你的测试用例

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 和外部接口,您可以编写测试来检查您的条目列表是否不为空。

public class Logger
{
  public List<Log> Entries = new List<Log>();

  ...
}
[TestCaseSource(nameof(something))]
    public void AddDebugSetAnonymusUserTest()
    {
        var logger = new Logger();
        logger.AddDebug("Text", null);

       //here is the check if AddDebug was successful
       Assert.AreEqual(1, logger.Entries.Count);

       //check if user was anonymous
       Assert.AreEqual("Anonymous", logger.Entries.FirstOrDefault().UserName);
    }

....

鉴于事实:

  • 你不能编辑 Logger class 这不是单元测试友好的
  • 该实现不会将 Entries 公开为 public 信息,也不会将其作为参数 Logger 传递给
  • none 的方法是虚拟的。

您必须使用反射来获得 Entries

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");

但是,这通常/可以说不被视为单元测试中的良好做法,因为这依赖于 Logger class 的内部结构,并且如果您更改Logger,这个单元测试可以破解。

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