我正在为我的项目编写命令行界面.用户输入"create project foo",它找到负责"project"的控制器,然后调用该Create方法,将"foo"作为第一个参数传递.
它在很大程度上依赖于属性和反射:控制器看起来像这样:
[ControllerFor("project")]
class ProjectController
{
[ControllerAction("create")]
public object Create(string projectName) { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)
我想在解析器的单元测试中使用Moq,如下所示:
Mock<IProjectsController> controller = new Mock<IProjectsController>();
controller.Expect(f => f.Create("foo"));
parser.Register(controller.Object);
parser.Execute("create project foo");
controller.VerifyAll();
Run Code Online (Sandbox Code Playgroud)
将属性添加到接口似乎不起作用 - 它们不是由派生类继承的.
我可以让Moq为被模拟的类添加属性吗?
(如标签所示,我使用的是moq).
我有这样的界面:
interface ISource
{
string Name { get; set; }
int Id { get; set; }
}
interface IExample
{
string Name { get; }
ISource Source { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,IExample的具体实例接受DTO(IDataTransferObject)作为Source.IExample的具体实现的一些属性只是委托给Source.像这样...
class Example : IExample
{
IDataTransferObject Source { get; set; }
string Name { get { return _data.Name; } }
}
Run Code Online (Sandbox Code Playgroud)
我想创建的IExample的一个独立的模拟(独立的意思,我不能使用捕获变量,因为模拟的IExample的几个实例将在测试的过程中创建)并设置这样的模拟是IExample.Name返回的值IExample.Source.Name.所以,我想创建一个这样的模拟:
var example = new Mock<IExample>();
example.SetupProperty(ex => ex.Source);
example.SetupGet(ex => ex.Name).Returns(what can I put here to return ex.Source.Name);
Run Code Online (Sandbox Code Playgroud)
本质上,我想配置mock作为一个属性的值,返回mock的子对象的属性值.
谢谢.
我有以下代码:
public interface IProductDataAccess
{
bool CreateProduct(Product newProduct);
}
Run Code Online (Sandbox Code Playgroud)
类ProductDataAccess实现了该接口.
public class ProductBusiness
{
public bool CreateProduct(Product newProduct)
{
IProductDataAccess pda = new ProductDataAccess();
bool result = pda.CreateProduct(newProduct);
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如何CreateProduct通过模拟IProductDataAccess接口来创建方法的单元测试?我想到了一个IProductDataAccess内部的公共实例ProductBusiness并使用Mock<IProductDataAccess>object 初始化它,但是将数据访问暴露给UI层并不是一个好习惯.谁能帮我?
是否可以在组装Returns对象时访问用于调用模拟期望的参数?
这是所涉及对象的存根,鉴于此,我试图模拟一个集合:
Class CollectionValue {
public Id { get; set; }
}
Class Collection {
private List<CollectionValue> AllValues { get; set; }
public List<CollectionValue> GetById(List<int> ids) {
return AllValues.Where(v => ids.Contains(v.Id));
}
}
Run Code Online (Sandbox Code Playgroud)
给定将用于模拟对象的CollectionValues测试列表,如何设置期望来处理CollectionValues列表中ID的每个可能排列,包括组合现有ID和不存在ID的调用?我的问题来自于希望在一次通话中建立所有可能的期望; 如果无法访问原始参数,我可以轻松地设置每次我想在给定调用中测试的确切期望.
这是我希望做的,"???" 表示访问用于调用GetById的参数(符合It.IsAny限制的参数)的方便位置:
CollectionMock.Expect(c => c.GetById(It.IsAny<List<int>>())).Returns(???);
Run Code Online (Sandbox Code Playgroud) 我一直看到DotNetKicks上提到的这个......然而却无法确切地知道它是什么(英文)或它的作用?你能解释它是什么,或者为什么我会用它?
我在工厂中有一个switch语句,它根据传入的枚举值返回一个命令.类似于:
public ICommand Create(EnumType enumType)
{
switch (enumType)
{
case(enumType.Val1):
return new SomeCommand();
case(enumType.Val2):
return new SomeCommand();
case(enumType.Val3):
return new SomeCommand();
default:
throw new ArgumentOutOfRangeException("Unknown enumType" + enumType);
}
}
Run Code Online (Sandbox Code Playgroud)
我目前为枚举中的每个值都有一个switch case.我对每种情况都进行了单元测试.如何对默认情况下的错误进行单元测试?显然,目前我无法传递一个未知的EnumType,但是谁说这将来不会改变.无论如何我是否可以纯粹为了单元测试而扩展或模拟EnumType?
在我的方法中,我有我的存储库这样做:
bool isConditionMet = MyRepository.Any(x => x.Condition == true);
Run Code Online (Sandbox Code Playgroud)
我试图使用MOQ来模拟这样:
MyMockedRepository.Setup(x => x.Any(y => y.Condition == true)).Returns(true);
Run Code Online (Sandbox Code Playgroud)
但是,当代码执行时,存储库调用始终返回false.
有没有办法用MOQ做到这一点?
**编辑 - 每个请求添加代码**
我正在使用NHibernate所以我的Any方法在我的基础存储库中并实现如下:
public virtual bool Any(Expression<Func<T, bool>> predicate)
{
return Session.Query<T>().Cacheable().Any(predicate);
}
Run Code Online (Sandbox Code Playgroud) 我想测试以下代码行:
...
Bitmap uploadedPicture = Bitmap.FromStream(model.Picture.InputStream) as Bitmap;
...
Run Code Online (Sandbox Code Playgroud)
Picture是我的模型类型HttpPostedFileBase中的属性.所以我想模拟一个HttpPostedFileBase属性进行单元测试:
model.Picture = new Mock<HttpPostedFileBase>().Object;
Run Code Online (Sandbox Code Playgroud)
没问题.
现在我必须模拟InputStream,否则它是null:
model.Picture.InputStream = new Mock<Stream>().Object;
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为InputStream是只读的(没有setter方法):
public virtual Stream InputStream { get; }
Run Code Online (Sandbox Code Playgroud)
是否有一个良好而干净的方法来处理这个问题?一种解决方案是在我的单元测试的派生类中重写HttpPostedFileBase.还有其他想法吗?
我正在尝试编写一个单元测试,我需要设置一个受保护的方法.我正在使用Moq进行此设置.
_innerHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", It.IsAny<HttpRequestMessage>(), It.IsAny<CancellationToken>())
.ReturnsAsync(responseMessage);
Run Code Online (Sandbox Code Playgroud)
当该行执行时,它会抛出以下异常:
System.ArgumentException:使用
ItExpr.IsNull<TValue>而不是null参数值,因为它阻止正确的方法查找.
当我将其更改为使用时ItExpr.IsNull<TValue>,它确实允许测试执行.但是,它当然缺少我想配置的设置.
为了使用It.IsAny<TValue>?设置受保护的方法,我需要做什么?
我有一个方法来获取标头值使用 IHttpContextAccessor
public class HeaderConfiguration : IHeaderConfiguration
{
public HeaderConfiguration()
{
}
public string GetTenantId(IHttpContextAccessor httpContextAccessor)
{
return httpContextAccessor.HttpContext.Request.Headers["Tenant-ID"].ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
我正在测试GetBookByBookId方法
假设该方法如下所示:
public class Book
{
private readonly IHttpContextAccessor _httpContextAccessor;
private IHeaderConfiguration _headerConfiguration;
private string _tenantID;
public Book(IHeaderConfiguration headerConfiguration, IHttpContextAccessor httpContextAccessor){
var headerConfig = new HeaderConfiguration();
_httpContextAccessor = httpContextAccessor;
_tenantID = headerConfig.GetTenantId(_httpContextAccessor);
}
public Task<List<BookModel>> GetBookByBookId(string id){
//do something with the _tenantId
//...
}
}
Run Code Online (Sandbox Code Playgroud)
这是我对GetBookByBookId方法的单元测试
[Fact]
public void test_GetBookByBookId()
{
//Arrange
//Mock IHttpContextAccessor
var …Run Code Online (Sandbox Code Playgroud) moq ×10
c# ×9
unit-testing ×7
mocking ×3
.net ×2
asp.net-core ×1
asp.net-mvc ×1
attributes ×1
predicate ×1