public void Pay()
{
// some insert db code
// ...
// Call Bank api
BankApi api = new BankApi();
int result = api.pay();
if(result == 1)
{
//...
}
else
{
//...
}
}
我不想在单元测试中调用api
。如何在不修改内码的情况下模拟pay方法(例如行new BankApi()
代码)?
答案 0 :(得分:3)
可以在不更改任何遗留代码的情况下模拟BankApi类,只需要一个允许模拟具体类的单元测试框架。 例如,使用Typemock测试您的方法:
[TestMethod]
public void ExampleTest()
{
//fakes the next BankApi instace
var handler = Isolate.Fake.NextInstance<BankApi>();
//change the pay method behavior
Isolate.WhenCalled(() => handler.pay()).WillReturn(1);
new ClassUnderTest().Pay();
}
答案 1 :(得分:2)
首先,如上所述,您应该创建一个接口。
import os
start_dir = os.getcwd()
for t in [1, 2, 3]:
this_dir_rel = "../data/train/Type_%d" % ( t )
this_dir_abs = os.path.join(start_dir, this_dir_rel)
os.chdir(this_dir_abs)
然后,你可以做的是像这样模拟这个界面(我在这里使用Moq“模拟你”,你需要添加NuGet包“Moq”作为你的应用程序的参考,你可以使用其他模拟当然是图书馆)
public interface IBankApi
{
int pay();
}
之后你会告诉这个电话应该返回什么(这将是真正的嘲笑)
apiMock = new Mock<IBankApi>();
然后,这个api“伪对象”可以通过使用apiMock.Object
来使用现在,我刚给你的这些信息并没有直接解决你的问题。
如评论中所述,您需要更好地解耦代码。
例如,您需要某种“依赖注入”来允许这种解耦。
以下是一个如何完成的简单示例:
apiMock.Setup(x => x.pay()).Returns(1); //
如何对该方法进行单元测试:
public class ClassThatUsesYourBankApi
{
private readonly IBankApi _api;
// the constructor will be given a reference to the interface
public ClassThatUsesYourBankApi (IBankApi api)
{
// here you could check for null parameter and throw exception as needed
this._api = api;
}
// this method can now be tested with the mock interface
public void MethodThatUseTheApi()
{
int result = this._api.pay();
if (result == 1)
{
// some things that happens
}
else
{
// some other thing
}
}
}
这里要理解的关键是,你不能在想要测试的方法中实例化你需要的api
换句话说,通过编程到接口来完成将你的方法与你的api“解耦”,以及你没有的代码
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
[TestClass]
public class TestMyMethod
{
[TestMethod]
public void MyMethod_WithBankApiReturns1_ShouldHaveThingsThatHappens()
{
// Arrange
var apiMock = new Mock<IBankApi>();
apiMock.Setup(api => api.pay())
.Returns(1);
var myObject = new ClassThatUsesYourBankApi(apiMock.Object);
// Act
int result = myObject.MethodThatUseTheApi();
// Assert
// Here you test that the things that should have happened when the api returns 1 actually have happened.
}
}
直接在你想要进行单元测试的方法中。
我展示了一种方法,还有其他方法。