英文:
C# Mocked service does not return correct values
问题
I've translated the code portion you provided into English:
I have an ASP.NET Core 6 web app where I display news. It has a `Bulgaria` action method that returns up to 30 news on a page.
Using Selenium and Moq, I am trying to write a test to check if the result is not null and if it displays 30 news.
Initially, the test passed and everything seemed fine. However, I noticed that the 30 news were actually from the real database instead of the fake ones I had prepared. Subsequently, I changed the fake news to 20 and modified the test to verify if there were 20 news, but it started to fail because it still returned 30 from the real database.
I have been working on this for about a day and a half now. Since I don't have much experience in testing, especially with Selenium and Moq, I haven't been able to figure out the problem yet.
Here is my `ControllerTest.cs`:
[Fact]
public void BulgariaDisplaysThirtyNewsAndIsNotNull()
{
// Arrange
var mockNewsService = new Mock<INewsService>();
// Create 20 fake news items
var fakeNewsItems = new List<NewsModel>();
for (int i = 0; i < 20; i++)
{
var fakeNewsItem = new NewsModel
{
Id = i + 1,
Title = $"Fake News {i + 1}",
Content = $"This is fake news {i + 1}"
};
fakeNewsItems.Add(fakeNewsItem);
}
var pageNumber = 1;
var numberOfNewsOnPage = 10;
var allNews = 20;
var totalPages = 2;
mockNewsService.Setup(service => service.RetrieveAllNewsCountAsync())
.ReturnsAsync(allNews);
mockNewsService.Setup(service => service.RetrieveAllNewsForThePageAsync(pageNumber, numberOfNewsOnPage))
.ReturnsAsync(fakeNewsItems);
var newsController = new NewsController(mockNewsService.Object, null);
// Act
var result = newsController.Bulgaria(pageNumber).GetAwaiter().GetResult();
// Assert
Assert.NotNull(result);
Assert.IsType<ViewResult>(result);
var viewResult = (ViewResult)result;
Assert.IsType<DisplayListOfNewsViewModel>(viewResult.Model);
var viewModel = (DisplayListOfNewsViewModel)viewResult.Model;
Assert.Equal(fakeNewsItems, viewModel.News);
Assert.Equal(20, viewModel.News.Count);
}
Here is my Bulgaria
action method and the NewsController
it is in:
public class NewsController : Controller
{
private readonly INewsService news;
private readonly IUserService users;
public NewsController(INewsService news, IUserService users)
{
this.news = news;
this.users = users;
}
public async Task<IActionResult> Bulgaria(int? pageNumber)
{
var numberOfNewsOnPage = ControllerConstants.NumberOfNewsOnAPage;
if (pageNumber == null)
{
pageNumber = 1;
}
var allNews = await this.news.RetrieveAllNewsCountAsync();
if (pageNumber < 1)
{
return RedirectToAction("Bulgaria", new { pageNumber = 1 });
}
var newsOnThePage = await this.news.RetrieveAllNewsForThePageAsync(pageNumber, numberOfNewsOnPage);
var totalPages = (int)Math.Ceiling((double)allNews / numberOfNewsOnPage);
if (pageNumber > totalPages)
{
return RedirectToAction("Bulgaria", new { pageNumber = totalPages });
}
var viewModel = new DisplayListOfNewsViewModel
{
News = newsOnThePage,
PageNumber = pageNumber.Value,
NumberOfNewsOnPage = numberOfNewsOnPage,
TotalNewsCount = allNews,
TotalPages = totalPages
};
return View(viewModel);
}
}
And here is my NewsService.cs
with only the used methods just to be sure:
namespace NewsWebSiteScraper.Services.News
{
using Microsoft.EntityFrameworkCore;
using NewsWebSiteScraper.Data;
using NewsWebSiteScraper.Data.Models;
using NewsWebSiteScraper.Models.News;
public class NewsService : INewsService
{
private readonly NewsWebSiteScraperDbContext data;
public NewsService(NewsWebSiteScraperDbContext data)
{
this.data = data;
}
public async Task<List<NewsModel>> RetrieveAllNewsForThePageAsync(int? pageNumber, int numberOfNewsOnPage)
{
var allNews = await this.data
.News
.OrderByDescending(n => n.Date)
.Where(n => n.Date != new DateTime(1000, 1, 1, 12, 30, 0))
.Select(n => new NewsModel
{
Id = n.Id,
Title = n.Title,
ImageUrl = n.ImageUrl
})
.Skip((pageNumber.Value - 1) * numberOfNewsOnPage)
.Take(numberOfNewsOnPage)
.ToListAsync();
return allNews;
}
public async Task<int> RetrieveAllNewsCountAsync()
{
var totalNewsCount = await this.data
.News
.Where(n => n.Date != new DateTime(1000, 1, 1, 12, 30, 0))
.CountAsync();
return totalNewsCount;
}
}
}
Please note that the code may require further debugging and adjustment based on your specific application and requirements.
英文:
I have an ASP.NET Core 6 web app where I display news. It has a Bulgaria
action method that returns up to 30 news on a page.
Using Selenium and Moq, I am trying to write a test to check if the result is not null and if it displays 30 news.
Initially, the test passed and everything seemed fine. However, I noticed that the 30 news were actually from the real database instead of the fake ones I had prepared. Subsequently, I changed the fake news to 20 and modified the test to verify if there were 20 news, but it started to fail because it still returned 30 from the real database.
I have been working on this for about a day and a half now. Since I don't have much experience in testing, especially with Selenium and Moq, I haven't been able to figure out the problem yet.
Here is my ControllerTest.cs
:
[Fact]
public void BulgariaDisplaysThirtyNewsAndIsNotNull()
{
// Arrange
var mockNewsService = new Mock<INewsService>();
// Create 20 fake news items
var fakeNewsItems = new List<NewsModel>();
for (int i = 0; i < 20; i++)
{
var fakeNewsItem = new NewsModel
{
Id = i + 1,
Title = $"Fake News {i + 1}",
Content = $"This is fake news {i + 1}"
};
fakeNewsItems.Add(fakeNewsItem);
}
var pageNumber = 1;
var numberOfNewsOnPage = 10;
var allNews = 20;
var totalPages = 2;
mockNewsService.Setup(service => service.RetrieveAllNewsCountAsync())
.ReturnsAsync(allNews);
mockNewsService.Setup(service => service.RetrieveAllNewsForThePageAsync(pageNumber, numberOfNewsOnPage))
.ReturnsAsync(fakeNewsItems);
var newsController = new NewsController(mockNewsService.Object, null);
// Act
var result = newsController.Bulgaria(pageNumber).GetAwaiter().GetResult();
// Assert
Assert.NotNull(result);
Assert.IsType<ViewResult>(result);
var viewResult = (ViewResult)result;
Assert.IsType<DisplayListOfNewsViewModel>(viewResult.Model);
var viewModel = (DisplayListOfNewsViewModel)viewResult.Model;
Assert.Equal(fakeNewsItems, viewModel.News);
Assert.Equal(20, viewModel.News.Count);
}
Here is my Bulgaria
action method and the NewsController
it is in:
public class NewsController : Controller
{
private readonly INewsService news;
private readonly IUserService users;
public NewsController(INewsService news, IUserService users)
{
this.news = news;
this.users = users;
}
public async Task<IActionResult> Bulgaria(int? pageNumber)
{
var numberOfNewsOnPage = ControllerConstants.NumberOfNewsOnAPage;
if (pageNumber == null)
{
pageNumber = 1;
}
var allNews = await this.news.RetrieveAllNewsCountAsync();
if (pageNumber < 1)
{
return RedirectToAction("Bulgaria", new { pageNumber = 1 });
}
var newsOnThePage = await this.news.RetrieveAllNewsForThePageAsync(pageNumber, numberOfNewsOnPage);
var totalPages = (int)Math.Ceiling((double)allNews / numberOfNewsOnPage);
if (pageNumber > totalPages)
{
return RedirectToAction("Bulgaria", new { pageNumber = totalPages });
}
var viewModel = new DisplayListOfNewsViewModel
{
News = newsOnThePage,
PageNumber = pageNumber.Value,
NumberOfNewsOnPage = numberOfNewsOnPage,
TotalNewsCount = allNews,
TotalPages = totalPages
};
return View(viewModel);
}
}
And here is my NewsService.cs
with only the used methods just to be sure:
namespace NewsWebSiteScraper.Services.News
{
using Microsoft.EntityFrameworkCore;
using NewsWebSiteScraper.Data;
using NewsWebSiteScraper.Data.Models;
using NewsWebSiteScraper.Models.News;
public class NewsService : INewsService
{
private readonly NewsWebSiteScraperDbContext data;
public NewsService(NewsWebSiteScraperDbContext data)
{
this.data = data;
}
public async Task<List<NewsModel>> RetrieveAllNewsForThePageAsync(int? pageNumber, int numberOfNewsOnPage)
{
var allNews = await this.data
.News
.OrderByDescending(n => n.Date)
.Where(n => n.Date != new DateTime(1000, 1, 1, 12, 30, 0))
.Select(n => new NewsModel
{
Id = n.Id,
Title = n.Title,
ImageUrl = n.ImageUrl
})
.Skip((pageNumber.Value - 1) * numberOfNewsOnPage)
.Take(numberOfNewsOnPage)
.ToListAsync();
return allNews;
}
public async Task<int> RetrieveAllNewsCountAsync()
{
var totalNewsCount = await this.data
.News
.Where(n => n.Date != new DateTime(1000, 1, 1, 12, 30, 0))
.CountAsync();
return totalNewsCount;
}
}
}
答案1
得分: 0
原来整个问题出在 Bulgaria
操作方法中。在第一行 - var numberOfNewsOnPage = ControllerConstants.NumberOfNewsOnAPage;
它设置了 numberOfNewsOnPage
变量,后来在服务方法中使用。在测试中,如果我没有提供正确的值,它就无法匹配服务方法,问题就出现了。
英文:
Turns out that the whole problem was in the Bulgaria
action method. At the first line - var numberOfNewsOnPage = ControllerConstants.NumberOfNewsOnAPage;
it sets the numberOfNewsOnPage
variable that are later used in the service method. And in the test if I don't give the correct value it does not match the service method and the problem occurs.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论