我有以下(简化)代码。
public class Controller
{
private readonly IService _service;
public Controller(IService service)
{
_service = service;
}
public async Task<IHttpActionResult> Create(MyObject object)
{
var result = _service.method(object);
if (!result.Succeeded)
{
return this.GetErrorResult(object);
}
}
}
和SimpleInjector用于在_service和它的实现类之间注入依赖关系,如下所示:
public static void Register(Container container)
{
container.Register<IService, Service>();
}
作为一个注释,注射和单元测试对我来说是新的,所以我不完全理解它们,但我正在学习。
如果我通过Swagger运行应用程序,一切正常。
注意,当我通过Swagger运行应用程序时,会调用Register
函数。
现在,我正在尝试使用NUnit设置一些单元测试,并且像这样模拟IService对象:
var Service = new Mock<IService>();
Controller _controller = new Controller(Service.Object);
_controller.Create(new MyObject object());
到目前为止,这对我来说似乎是正确的 - 虽然我不确定?
问题是,对于单元测试,result
总是为空 - 我认为这是因为我的Mock接口存在问题 - 它似乎没有找到方法 - 它从不步骤进入它并且没有显示在调试器中。
注意,对于单元测试,Register
方法不会被调用。我确实试着调用它来注册依赖项,但它没有帮助。
正如我上面所说,这对我来说是全新的,我对所有这一切都处于理解的边缘。
我没有想法,也不知道从哪里看,所以任何帮助都会非常感激。
编辑:
原始问题如下:
public async Task<IHttpActionResult> Create(string content)
我已更新为:
public async Task<IHttpActionResult> Create(MyObject object)
任何人都可以建议我如何在设置中传递MyObject
的通用引用,而不必创建此类的实例。
所以基本上我想告诉它将传入这个类的实例,而不创建该实例。
我尝试了以下内容:
Service.Setup(x => x.method(It.IsAny<MyObject>())
but it says cannot convert MethodGroup to MyObject
以下是IService的定义:
public interface IService
{
IdentityResult method(ApplicationUser user, UserLoginInfo login);
}
答案 0 :(得分:4)
必须在Mock对象上调用setup方法。
var Service = new Mock<IService>();
Service.Setup(x=>x.method("argument")).Returns(YourReturnObject)
Controller _controller = new Controller(Service.Object);
答案 1 :(得分:2)
您需要配置Mock
对象以返回IService.method
的内容,如下所示:
var Service = new Mock<IService>();
Service.Setup(x => x.method(It.IsAny<string>())
.Returns<string>(str => **whatever result you need**);
添加实际IService
定义后,您应将Setup
调用更改为:
Service.Setup(x => x.method(It.IsAny<ApplicationUser>(), It.IsAny<UserLoginInfo>())
.Returns<ApplicationUser, UserLoginInfo>((user, login) => new IdentityResult(true));
答案 2 :(得分:2)
使用简化示例
public class Controller
{
private readonly IService _service;
public Controller(IService service)
{
_service = service;
}
public async Task<IHttpActionResult> Create(string content)
{
var result = await _service.method(content);
if (!result.Succeeded)
{
return this.GetErrorResult(result);
}
return Ok();
}
}
让我们假设IService被定义为
public interface IService {
Task<Result> method(string input);
}
public class Result {
public bool Succeeded { get; set; }
}
对于单元测试,您需要设置模拟以伪造测试所需的操作
public async Task Controller_Given_Content_Should_Return_Ok() {
//Arrange
var input = "content";
var mockService = new Mock<IService>();
mockService
.Setup(m => m.method(input))
.ReturnAsync(new Result { Succeeded = true });
var _controller = new Controller(mockService.Object);
//Act
var result = await _controller.Create(input);
//Assert
Assert.IsNotNull(result);
Assert.IsInstanceOfType(result,typeof(OkResult));
}
鉴于被测方法是异步的,您可能希望将测试设置为异步。