在我的工作中,我们使用Moq进行模拟,使用Unity作为IOC容器.我对此很新,并且没有很多资源可以帮助我确定我应该使用的最佳实践.
现在,我有一组特定进程需要用来完成其工作的存储库接口(例如:IRepository1,IRepository2 ... IRepository4).
在实际代码中,我可以使用IOC容器并使用RegisterType()方法确定所有IRepository对象.
我试图找出能够测试需要4个提到的存储库的方法的最佳方法.
我想我可以只注册一个Unity IOC容器的新实例,并在每个模拟对象的容器上调用RegisterInstance,为每个模拟对象传递Mock.Object值.我试图使这个注册过程可重用,所以除了单元测试需要从存储库返回一些特定数据之外,我不必一遍又一遍地对每个单元测试做同样的事情.这就是问题所在......在模拟存储库上设置期望值的最佳做法是什么?好像我只是在Unity容器上调用RegisterType,我将失去对实际Mock对象的引用,并且无法覆盖行为.
这是使用NUnit和Moq从ASP.NET MVC项目中的一个控制器进行的单元测试:
[Test]
public void Create_job_with_modelstate_errors_fails()
{
var job = new JobDto();
this.controller.ModelState.AddModelError("", "");
ActionResult result = this.controller.Create(job);
this.jobService.Verify(p => p.SaveJob(It.IsAny<JobDto>()), Times.Never());
// some other asserts removed for brevity
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但从维护的角度来看,我认为这一行比它需要的更冗长:
this.postService.Verify(p => p.SavePost(It.IsAny<PostDto>()), Times.Never());
Run Code Online (Sandbox Code Playgroud)
我真正希望能够做的是......
this.postService.VerifyNoMethodsCalled();
Run Code Online (Sandbox Code Playgroud)
...因为我感兴趣的是我的控制器不会调用服务上的任何方法.这可能使用Moq吗?
如何设置我的Moq以返回一些值并让测试的服务选择正确的?
IRepository:
public interface IGeographicRepository
{
IQueryable<Country> GetCountries();
}
Run Code Online (Sandbox Code Playgroud)
服务:
public Country GetCountry(int countryId)
{
return geographicsRepository.GetCountries()
.Where(c => c.CountryId == countryId).SingleOrDefault();
}
Run Code Online (Sandbox Code Playgroud)
测试:
[Test]
public void Can_Get_Correct_Country()
{
//Setup
geographicsRepository.Setup(x => x.GetCountries()).Returns()
//No idea what to do here.
//Call
var country = geoService.GetCountry(1);
//Should return object Country with property CountryName="Jamaica"
//Assert
Assert.IsInstanceOf<Country>(country);
Assert.AreEqual("Jamaica", country.CountryName);
Assert.AreEqual(1, country.CountryId);
geographicsRepository.VerifyAll();
}
Run Code Online (Sandbox Code Playgroud)
我基本上坚持设置.
我有一个依赖于User.Identity.Name的动作来获取当前用户的用户名以获取他的订单列表:
public ActionResult XLineas()
{
ViewData["Filtre"] = _options.Filtre;
ViewData["NomesPendents"] = _options.NomesPendents;
return View(_repository.ObteLiniesPedido(User.Identity.Name,_options.Filtre,_options.NomesPendents));
}
Run Code Online (Sandbox Code Playgroud)
现在我正在尝试为此编写单元测试,但我不知道如何为User.Identity.Name提供模拟.如果我按照我的方式运行我的测试(没有模拟用户...),我得到一个Null ..异常.
这是正确的方法吗?我认为我的Action代码不适合单元测试.
我正在学习测试驱动开发并尝试使用Moq库进行模拟.Mock类的Setup方法的目的是什么?
使用Moq,如何使用输入参数设置方法调用作为具有预期属性值的对象?
var storageManager = new Mock<IStorageManager>();
storageManager.Setup(e => e.Add(It.IsAny<UserMetaData>()));
Run Code Online (Sandbox Code Playgroud)
Add()方法需要具有FirstName属性的UserMetaData对象.
我想确保传递了具有FirstName为"FirstName1"的UserMetaData类型的对象.
我正在尝试测试一些依赖于ControllerContext.RouteData中的Values属性的应用程序逻辑.
到目前为止我有
// Arrange
var httpContextMock = new Mock<HttpContextBase>(MockBehavior.Loose);
var controllerMock = new Mock<ControllerBase>(MockBehavior.Loose);
var routeDataMock = new Mock<RouteData>();
var wantedRouteValues = new Dictionary<string, string>();
wantedRouteValues.Add("key1", "value1");
var routeValues = new RouteValueDictionary(wantedRouteValues);
routeDataMock.SetupGet(r => r.Values).Returns(routeValues); <=== Fails here
var controllerContext = new ControllerContext(httpContextMock.Object, routeDataMock.Object, controllerMock.Object);
Run Code Online (Sandbox Code Playgroud)
单元测试失败:System.ArgumentException:不可覆盖的成员上的设置无效:r => r.Values
由于构造函数是RouteData(RouteBase,IRouteHandler),因此创建伪RouteData也不起作用.
这里重要的类是抽象类RouteBase,它有GetRouteData(HttpContextBase)方法,它返回一个RouteData实例,我试图伪造的类.把我带到圈子里!
对此的任何帮助都是最受欢迎的.
我有一个演示者类,它附加了注入视图的事件.现在我想测试演示者对事件的正确反应.
这是视图界面IView:
public interface IView
{
event EventHandler MyEvent;
void UpdateView(string test);
}
Run Code Online (Sandbox Code Playgroud)
这是实现IView的视图
public partial class MyView : IView
{
public event EventHandler MyEvent;
public MyView()
{
this.combo.SelectedIndexChanged += this.OnSelectedIndexChanged;
}
public void UpdateView(string test)
{
this.textBox.Text = test;
}
private OnSelectedIndexChanged(Object sender, EventArgs e)
{
if (this.MyEvent != null)
{
this.MyEvent(sender, e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是受测试的主持人:
public class MyPresenter
{
private IView _view;
public MyPresenter(IView view)
{
this._view = view;
this._view.MyEvent += this.OnMyEvent;
}
private void OnMyEvent(Object sender, …Run Code Online (Sandbox Code Playgroud) 我得到了一个通过参数得到代表的类.这个类调用该委托,我想用Moq对它进行单元测试.我如何验证这个方法被调用?
示例类:
public delegate void Foo(int number);
public class A
{
int a = 5;
public A(Foo myFoo)
{
myFoo(a);
}
}
Run Code Online (Sandbox Code Playgroud)
我想检查Foo是否被调用.谢谢.
moq ×10
unit-testing ×7
c# ×5
asp.net-mvc ×3
nunit ×3
tdd ×3
mocking ×2
.net ×1
delegates ×1
html-helper ×1