gpt4 book ai didi

c# - 模拟 ViewModel 以使用 Moq 进行单元测试?

转载 作者:行者123 更新时间:2023-11-30 16:55:50 25 4
gpt4 key购买 nike

单元测试的新手。我有一个 WPF 客户端应用程序通过 basicHttpbinding 连接到 WCF 服务。一切都很好。我在我的 viewModel 中使用简单的构造函数依赖注入(inject),传入一个 IServiceChannel,然后我将其称为服务方法,例如:

IMyserviceChannel = MyService;

public MyViewModel(IMyServiceChannel myService)
{
this.MyService = myService;
}

Private void GetPerson()
{
var selectedPerson = MyService.GetSelectedPerson();
}

然后我在客户端应用程序中添加了一个 MS 测试项目,我正在尝试使用 Moq 来模拟我的服务:

  [TestMethod]
public void GetArticleBody_Test_Valid()
{
// Create channel mock
Mock<IIsesServiceChannel> channelMock = new Mock<IIsesServiceChannel>(MockBehavior.Strict);

// setup the mock to expect the Reverse method to be called
channelMock.Setup(c => c.GetArticleBody(1010000008)).Returns("110,956 bo/d, 1.42 Bcfg/d and 4,900 bc/d. ");

// create string helper and invoke the Reverse method
ArticleDataGridViewModel articleDataGridViewModel = new ArticleDataGridViewModel(channelMock.Object);
string result = channelMock.GetArticleBody(1010000008);
//Assert.AreEqual("cba", result);

//verify that the method was called on the mock
channelMock.Verify(c => c.GetArticleBody(1010000008), Times.Once());
}

测试失败,出现 System.NullReferenceException。对象引用未设置为对象的实例。 在此处的方法调用处:

 string result = articleDataGridViewModel.IsesService.GetArticleBody(1010000008);

所以我在想这是否是最好的方法,或者我是否更好地以某种方式模拟适用于测试的 viewModel 的孤立部分?

最佳答案

我会抛出 NullReferenceException,因为您使用了 MockBehavior.Strict。文档说:

Causes this mock to always throw an exception for invocations that don't have a corresponding setup.

ArticleDataGridViewModel 的构造函数可能会调用您尚未设置的服务的其他方法。另一个问题是,您正在直接调用模拟方法。相反,您应该调用 View 模型的一个方法,该方法调用此方法。

[TestMethod]
public void GetArticleBody_Test_Valid()
{
// Create channel mock
Mock<IIsesServiceChannel> channelMock = new Mock<IIsesServiceChannel>();

// setup the mock to expect the Reverse method to be called
channelMock.Setup(c => c.GetArticleBody(1010000008)).Returns("110,956 bo/d, 1.42 Bcfg/d and 4,900 bc/d. ");

// create string helper and invoke the Reverse method
ArticleDataGridViewModel articleDataGridViewModel = new ArticleDataGridViewModel(channelMock.Object);
string result = articleDataGridViewModel.MethodThatCallsService();
//Assert.AreEqual("cba", result);

//verify that the method was called on the mock
channelMock.Verify(c => c.GetArticleBody(1010000008), Times.Once());
}

除此之外,我认为您的方法没有问题。也许 View 模型违反了单一责任原则并且做了比它应该做的更多的事情,但是根据您的代码示例很难判断。

编辑:这是一个完整的例子,说明如何测试这样的东西:

public interface IMyService
{
int GetData();
}

public class MyViewModel
{
private readonly IMyService myService;

public MyViewModel(IMyService myService)
{
if (myService == null)
{
throw new ArgumentNullException("myService");
}

this.myService = myService;
}

public string ShowSomething()
{
return "Just a test " + this.myService.GetData();
}
}

class TestClass
{
[TestMethod]
public void TestMethod()
{
var serviceMock = new Mock<IMyService>();
var objectUnderTest = new MyViewModel(serviceMock.Object);

serviceMock.Setup(x => x.GetData()).Returns(42);

var result = objectUnderTest.ShowSomething();

Assert.AreEqual("Just a test 42", result);
serviceMock.Verify(c => c.GetData(), Times.Once());
}
}

关于c# - 模拟 ViewModel 以使用 Moq 进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28942670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com