这是我的控制器:
public class BlogController : Controller
{
private IDAO<Blog> _blogDAO;
private readonly ILogger<BlogController> _logger;
public BlogController(ILogger<BlogController> logger, IDAO<Blog> blogDAO)
{
this._blogDAO = blogDAO;
this._logger = logger;
}
public IActionResult Index()
{
var blogs = this._blogDAO.GetMany();
this._logger.LogInformation("Index page say hello", new object[0]);
return View(blogs);
}
}
如你所见,我有两个依赖项,一个IDAO
和一个ILogger
这是我的测试类,我使用xUnit进行测试,使用Moq创建mock和stub,我可以轻松地模拟DAO
,但使用ILogger
我不知道该怎么做,所以在运行测试时,我只传递null并注释掉登录控制器的调用。有没有一种方法可以进行测试,但仍然以某种方式保留记录器?
public class BlogControllerTest
{
[Fact]
public void Index_ReturnAViewResult_WithAListOfBlog()
{
var mockRepo = new Mock<IDAO<Blog>>();
mockRepo.Setup(repo => repo.GetMany(null)).Returns(GetListBlog());
var controller = new BlogController(null,mockRepo.Object);
var result = controller.Index();
var viewResult = Assert.IsType<ViewResult>(result);
var model = Assert.IsAssignableFrom<IEnumerable<Blog>>(viewResult.ViewData.Model);
Assert.Equal(2, model.Count());
}
}
更新(感谢@Gopal Krishnan的评论):
用最小起订量
loggerMock.Verify(
x => x.Log(
LogLevel.Information,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) => string.Equals("Index page say hello", o.ToString(), StringComparison.InvariantCultureIgnoreCase)),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception, string>>()),
Times.Once);
以前版本的答案(对于Moq
对于使用最小起订量的net core 3答案
由于ILogger中的问题TState中描述的更改,不再工作。日志以前是对象,现在格式化为LogValues
幸运的是,stakx提供了一个不错的解决方案。所以我把它贴出来,希望它能为其他人节省时间(花了一段时间才弄清楚):
loggerMock.Verify(
x => x.Log(
LogLevel.Information,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) => string.Equals("Index page say hello", o.ToString(), StringComparison.InvariantCultureIgnoreCase)),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>) It.IsAny<object>()),
Times.Once);
实际上,我已经找到了微软。扩展。登录中。抽象。空记录器
using Microsoft.Extensions.Logging;
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
...
}
using Microsoft.Extensions.Logging;
public class MyClass : IMyClass
{
public const string ErrorMessageILoggerFactoryIsNull = "ILoggerFactory is null";
private readonly ILogger<MyClass> logger;
public MyClass(ILoggerFactory loggerFactory)
{
if (null == loggerFactory)
{
throw new ArgumentNullException(ErrorMessageILoggerFactoryIsNull, (Exception)null);
}
this.logger = loggerFactory.CreateLogger<MyClass>();
}
}
和单元测试
//using Microsoft.VisualStudio.TestTools.UnitTesting;
//using Microsoft.Extensions.Logging;
[TestMethod]
public void SampleTest()
{
ILoggerFactory doesntDoMuch = new Microsoft.Extensions.Logging.Abstractions.NullLoggerFactory();
IMyClass testItem = new MyClass(doesntDoMuch);
Assert.IsNotNull(testItem);
}
只要把它和任何其他依赖性都模仿一下:
var mock = new Mock<ILogger<BlogController>>();
ILogger<BlogController> logger = mock.Object;
//or use this short equivalent
logger = Mock.Of<ILogger<BlogController>>()
var controller = new BlogController(logger);
您可能需要安装Microsoft。扩展。登录中。摘要要使用的包ILogger
此外,您可以创建一个真正的记录器:
var serviceProvider = new ServiceCollection()
.AddLogging()
.BuildServiceProvider();
var factory = serviceProvider.GetService<ILoggerFactory>();
var logger = factory.CreateLogger<BlogController>();
单元测试,对独立的代码功能片段,由编写代码的团队进行测试,也是一种编码,而非与之不同的一些事情。设计代码的一部分就是设计它该如何被测试。你应该写一个测试计划,即使它只是一句话。有时候测试很简单:“这个按钮看起来好吗?”,有时候它很复杂:“这个匹配算法可以精确地返回正确的匹配结果?”。 无论任何可能的时候,使用断言检查以及测试驱动。这不仅能尽早发现 bug,而且在之后也很有用,让你在其他方面担心的谜
问题内容: 我选择的数据库是MongoDB。我正在编写一个数据层API,以从客户端应用程序中抽象实现细节- 也就是说,我实质上是在提供一个公共接口(一个充当IDL的对象)。 我正在以TDD方式测试自己的逻辑。在每个单元测试之前,调用一个方法来创建数据库单例,此后,当测试完成时,将调用一个方法来删除数据库。这有助于促进单元测试之间的独立性。 几乎所有单元测试(即 执行上下文查询 )都需要先进行某种插
我想测试以下骆驼路线。我在网上找到的所有例子都有以文件开头的路由,在我的例子中,我有一个Springbean方法,每隔几分钟就会被调用一次,最后消息被转换并移动到jms以及审计目录。 我对这条路线的写测试毫无头绪。目前我在测试用例中所拥有的是
我正在构建一个android应用程序,它使用Firebase作为后端,并采用模型、视图和演示者架构。然而,Firebase是一种云服务的事实使我的android应用程序中的自动测试变得复杂。到目前为止,我已经构建了大部分身份验证系统,但无法看到如何在我的应用程序中实现Firebase代码的单元测试。在端到端测试方面,我也陷入了困境。 由于测试是任何android应用程序的基础,没有it应用程序开发
问题内容: 是否有任何简单的机制可以覆盖Django单元测试的设置?我在一个模型上有一个经理,该经理返回特定数量的最新对象。它返回的对象数由NUM_LATEST设置定义。 如果有人更改设置,这可能会使我的测试失败。如何覆盖设置并随后恢复设置?如果不可能,是否可以通过某种方式猴子修补方法或模拟设置? 编辑:这是我的经理代码: 管理器用于切片查询集。该只是用来提供一个默认的应该设置不存在。 问题答案:
问题内容: 如何在单元测试中测试 hashCode()函数? 问题答案: 每当我覆盖equals和hash代码时,我都会按照Joshua Bloch在“ Effective Java”第3章中的建议编写单元测试。我确保equals和hash代码是自反的,对称的和可传递的。我还确保“不等于”对所有数据成员均正常工作。 当我检查对equals的调用时,我还要确保hashCode的行为符合预期。像这样: