注入模拟依赖到ViewModel,而单元测试不按预期行事

时间:2018-03-30 01:27:13

标签: c# unit-testing dependency-injection moq viewmodel

我试图通过使用Moq和依赖注入来在视图模型中进行单元测试

基本上,我有模型:类PersonModel包含属性FirstNameLastNameInputOutput - 这里没有逻辑或任何方法。< / p>

在我的ViewModel中,我有:

public class ViewModel
{
    private IGetService getService;
    private Personmodel personModel;
    private string result;

    public ViewModel(IGetService getService)
    {
        personModel= new Personmodel ();
        this.getService = getService;
    }

    public string FullName
    {
        get { return personModel.FirstName + " " + personModel.LastName; }
    }
    public string Result
    {
        get { return result; }
        set { result = value; }
    }

    public string FirstName
    {
        get { return personModel.FirstName; }
        set { personModel.FirstName = value; }
    }

    public string LastName
    {
        get { return personModel.LastName; }
        set { personModel.LastName = value; }
    }

    public string Input
    {
        get { return personModel.Input; }
        set { personModel.Input= value; }
    }

    public string Output
    {
        get { return personModel.Output; }
        set { personModel.Output= value; }
    }

    public string Result
    {
        get { return result; }
        set { result = value; }
    }        
    public void ResultFromModelToView()
    {
        getService.GetOutput(personModel);
        Result = string.Join(",", FullName,personModel.Output);            
    }
}

IGetService

public interface IGetService
{
    void GetOutput(PersonModel personModel);
}   

GetService的实现几乎获得了personModel.Outout值,具体取决于业务逻辑

这是我的ViewModelTests

public class ViewModelTests
{

    private Mock<IGetService> GetServiceMock{ get; set; }
    private ViewModel ViewModel { get; set; }

    [TestInitialize()]
    public void Initialize()
    {
        GetServiceMock= new Mock<IGetService>();
        ViewModel = new ViewModel (GetServiceMock.Object);
    }

    [TestMethod()]
    public void GetResultTests()
    {
        // Arrange
        GetServiceMock.Setup(x =>  x.GetOutput(It.Is<PersonModel>(
            p=> p.FirstName == "FirstName" &&
                    p.LastName == "LastName" &&
                    p.Input == "Input"
            )));

        // Act
        ViewModel.ResultFromModelToView();

        // Assert
        Assert.AreEqual(ViewModel.Result, "FirstName,LastName,Output");

    }
}

当我进行测试时,我正在

  

断言失败,预期结果为&#34; ,,&#34;

我错过了什么?

1 个答案:

答案 0 :(得分:0)

鉴于视图模型的设计,您没有为模型分配值,以允许根据模拟的设置方式完成测试。您还需要让模拟模仿在调用GetOutput时在模型上设置输出的预期行为。

断言中的期望也是错误的,因为ViewModel.FullName被定义为

public string FullName {
    get { return personModel.FirstName + " " + personModel.LastName; }
}

请注意名称之间的空格,而不是预期结果"FirstName,LastName,Output"的逗号。即使您向视图模型提供了必要的值,这也会导致测试失败。

根据提供的原始示例,查看对测试所做的以下更改

[TestClass]
public class ViewModelTests {

    private Mock<IGetService> GetServiceMock{ get; set; }
    private ViewModel ViewModel { get; set; }

    [TestInitialize()]
    public void Initialize()
    {
        GetServiceMock= new Mock<IGetService>();
        ViewModel = new ViewModel (GetServiceMock.Object);
    }

    [TestMethod()]
    public void GetResultTests() {
        // Arrange
        var expectedFirstName = "FirstName";
        var expectedLastName = "LastName";
        var expectedInput = "Input";
        var expectedOutput = "Output";
        var expectedResult = "FirstName LastName,Output";

        //set properties on view model
        ViewModel.FirstName = expectedFirstName;
        ViewModel.LastName = expectedLastName;
        ViewModel.Input = expectedInput;

        //Arrange mock to expect specific model
        GetServiceMock
            .Setup(_ => _.GetOutput(It.Is<PersonModel>(p=> 
                p.FirstName == expectedFirstName &&
                p.LastName == expectedLastName &&
                p.Input == expectedInput
            )))
            .Callback((PersonModel p) => { // <-- use callback to set Output on model
                p.Output = expectedOutput;
            });

        // Act
        ViewModel.ResultFromModelToView();
        actualResult = ViewModel.Result;

        // Assert
        Assert.AreEqual(expectedResult, actualResult);
    }
}