如何在单元测试中模拟一个函数
How to mock a function in an unit test
我如何通过 NMock3 对 GetData 进行单元测试?
如果可以模拟 prcessA.Run 和 ProcessA 中的 "result" 就好了。
IAnotherService 不能作为 GetData 的参数,因为它取决于 GetData 中的处理值。
有什么想法吗?
服务 1
public class Service1 : IService1
{
public Service1()
{
}
public string GetData(int a)
{
// some process depends on input
int b = a * new Random().Next();
IAnotherService anotherService = new AnotherService(b);
ProcessA processA = new ProcessA(anotherService);
processA.Run();
return processA.result;
}
}
简化流程A
public class ProcessA
{
public string result;
private IAnotherService anotherService;
public ProcessA(IAnotherService anotherService)
{
this.anotherService = anotherService;
}
public void Run()
{
// Some other process here
this.result = this.anotherService.Run();
}
}
测试方法 1
[TestMethod]
public void TestMethod1()
{
using (mockFactory.Ordered())
{
// Nothing to Mock
}
IService1 service1 = new Service1();
string aaa = service1.GetData(1);
Assert.AreEqual("XXX", aaa);
}
如前所述,您需要模拟相关服务并设置您期望的 return。
我在下面做了一个测试,它有效。我用的是Moq,但是原理是一样的
public interface IAnotherService
{
string Run();
}
public class ProcessA
{
public string result;
private readonly IAnotherService _anotherService;
public ProcessA(IAnotherService anotherService)
{
this._anotherService = anotherService;
}
public string Run()
{
// Some other process here
return _anotherService.Run();
}
}
然后运行测试
[Test]
public void TestMethod1()
{
//Create a Mock
var mockService = new Mock<IAnotherService>();
//Set the expected result
mockService.Setup(method => method.Run()).Returns("XXX");
//Inject the mock
var process = new ProcessA(mockService.Object);
var result = process.Run();
//Assert the result
Assert.AreEqual("XXX", result);
}
编辑
正如所讨论的,我已经编辑了我的答案,希望能满足您的需要。
public interface IService1
{
string GetData(int a);
int ValueForB { get; set; }
}
public class Service1Consumer : IService1
{
private readonly IAnotherService _anotherServiceImplementation;
public Service1Consumer(IAnotherService service)
{
_anotherServiceImplementation = service;
}
public string GetData(int a)
{
ValueForB = a * new Random().Next();
_anotherServiceImplementation.ValueFor = b;
var processA = new ProcessA(_anotherServiceImplementation);
return processA.Run();
}
}
public interface IAnotherService
{
int ValueForB { get; set; }
}
public class AnotherService : IAnotherService
{
}
public class ProcessA
{
public string result;
private readonly IAnotherService _anotherService;
public ProcessA(IAnotherService anotherService)
{
_anotherService = anotherService;
}
public string Run()
{
return "XXXX";
}
}
然后是测试。
[Test]
public void TestMethod1()
{
//Create a Mock
var mockAnotherService = new Mock<IAnotherService>();
//Set the property value when called.
mockAnotherService.Setup(method => method.ValueForB).Returns(10);//Test 1
var service1Consumer = new Service1Consumer(mockAnotherService.Object);
var result = service1Consumer.GetData();
Assert.AreEqual("XXXX",result);
}
希望这能为您指明正确的方向。
谢谢
我如何通过 NMock3 对 GetData 进行单元测试?
如果可以模拟 prcessA.Run 和 ProcessA 中的 "result" 就好了。
IAnotherService 不能作为 GetData 的参数,因为它取决于 GetData 中的处理值。
有什么想法吗?
服务 1
public class Service1 : IService1
{
public Service1()
{
}
public string GetData(int a)
{
// some process depends on input
int b = a * new Random().Next();
IAnotherService anotherService = new AnotherService(b);
ProcessA processA = new ProcessA(anotherService);
processA.Run();
return processA.result;
}
}
简化流程A
public class ProcessA
{
public string result;
private IAnotherService anotherService;
public ProcessA(IAnotherService anotherService)
{
this.anotherService = anotherService;
}
public void Run()
{
// Some other process here
this.result = this.anotherService.Run();
}
}
测试方法 1
[TestMethod]
public void TestMethod1()
{
using (mockFactory.Ordered())
{
// Nothing to Mock
}
IService1 service1 = new Service1();
string aaa = service1.GetData(1);
Assert.AreEqual("XXX", aaa);
}
如前所述,您需要模拟相关服务并设置您期望的 return。
我在下面做了一个测试,它有效。我用的是Moq,但是原理是一样的
public interface IAnotherService
{
string Run();
}
public class ProcessA
{
public string result;
private readonly IAnotherService _anotherService;
public ProcessA(IAnotherService anotherService)
{
this._anotherService = anotherService;
}
public string Run()
{
// Some other process here
return _anotherService.Run();
}
}
然后运行测试
[Test]
public void TestMethod1()
{
//Create a Mock
var mockService = new Mock<IAnotherService>();
//Set the expected result
mockService.Setup(method => method.Run()).Returns("XXX");
//Inject the mock
var process = new ProcessA(mockService.Object);
var result = process.Run();
//Assert the result
Assert.AreEqual("XXX", result);
}
编辑
正如所讨论的,我已经编辑了我的答案,希望能满足您的需要。
public interface IService1
{
string GetData(int a);
int ValueForB { get; set; }
}
public class Service1Consumer : IService1
{
private readonly IAnotherService _anotherServiceImplementation;
public Service1Consumer(IAnotherService service)
{
_anotherServiceImplementation = service;
}
public string GetData(int a)
{
ValueForB = a * new Random().Next();
_anotherServiceImplementation.ValueFor = b;
var processA = new ProcessA(_anotherServiceImplementation);
return processA.Run();
}
}
public interface IAnotherService
{
int ValueForB { get; set; }
}
public class AnotherService : IAnotherService
{
}
public class ProcessA
{
public string result;
private readonly IAnotherService _anotherService;
public ProcessA(IAnotherService anotherService)
{
_anotherService = anotherService;
}
public string Run()
{
return "XXXX";
}
}
然后是测试。
[Test]
public void TestMethod1()
{
//Create a Mock
var mockAnotherService = new Mock<IAnotherService>();
//Set the property value when called.
mockAnotherService.Setup(method => method.ValueForB).Returns(10);//Test 1
var service1Consumer = new Service1Consumer(mockAnotherService.Object);
var result = service1Consumer.GetData();
Assert.AreEqual("XXXX",result);
}
希望这能为您指明正确的方向。 谢谢