6

この GetData メソッドを単体テストする必要があります。

    public MessageResponse GetData(XmlElement requestElement)
    {   
        MessageResponse MsgResponse = new MessageResponse();


        if (requestElement.Attributes["employeeNo"] == null){
            MsgResponse.Messages = new List<string>();
            MsgResponse.Messages.Add("Attribute employeeNo is missing");
            MsgResponse.Error = true;
            return MsgResponse;
        }
        if (requestElement.Attributes["xmlEmployeeName"] == null){
            MsgResponse.Messages.Add("Attribute xmlEmployeeName is missing");
            MsgResponse.Error = true;
            return MsgResponse;
        }
        return MsgResponse;
    }

このメソッドには XmlElement パラメータが必要です。どのように私はそれを嘲笑しますか? 私のコードでは、最初に xmlDocument を作成し、次に xml ファイルを読み込みます。

            XmlDocument doc = new XmlDocument();
            doc.Load(xmlFilePath);
            requestElement = doc.DocumentElement;

私がそれをテストするには、最初にemployeeNoなしでxmlファイルを作成する必要があります.nameなしで別のファイルを作成する必要があります.おそらく他のシナリオではもっと多くの. 大変な作業のようです。それをテストするより良い方法はありますか?

テストを簡素化するためにmoqまたは他のテストフレームワークを使用する必要がありますか?

4

3 に答える 3

9

ファイルをまったく読み取らずに、テストする要素を作成するだけです。

var doc = new XmlDocument();
doc.LoadXml("<MyTestElement/>");
var myTestElement = doc.DocumentElement;
myTestElement.Attributes["employeeNo"] = "fakeId";

var response = myTestResponder.GetData(myTestElement);

//assert whatever you need to

注: テストを書くのが難しすぎることに気付くたびに、通常、これはクラス/メソッドがやりすぎていることを意味します。

提供されたデータで何かを行うよりも、メソッドが入力を検証すると思います。アプリケーションに必要なデータ モデルを作成するために、(xml デシリアライザーを使用して) データ読み取り部分を抽象化することをお勧めします。

次に、逆シリアル化されたデータの結果に対して検証を実行します。何かのようなもの:

public MessageResponse GetData(XmlElement requestElement)
{
   var data = _xmlDeserializer.Deserialize(requestElement);
   var validationResult = _validator.Validate(data);
    if (validationResult.Errors.Count > 0)
    {
         //populate errors
        return result;
    }

    _dataProcessor.DoSomethingWithData(data);
}

優れた検証ライブラリについては、FluentValidationをご覧ください。

上記のルートに進むと、テストははるかに簡単になります。

于 2013-11-01T18:50:06.277 に答える
1
[TestMethod]
public void GetData_Returns_Correct_Message_When_EmployeeNo_Is_Null()
{
    var inputWithoutEmployeeNo = GetElement(@"<input></input>");

    var actual = GetData(inputWithoutEmployeeNo);

    Assert.IsTrue(actual.Error, "Error should be true when employee no. is missing");
    Assert.IsNotNull(actual.Messages);
    Assert.AreEqual(1, actual.Messages.Count);
    Assert.AreEqual("Attribute employeeNo is missing", actual.Messages[0]);
}

private XmlElement GetElement(string xml)
{
    var doc = new XmlDocument();
    doc.LoadXml(xml);
    return doc.DocumentElement;
}

単体テストの作業中に、コードが NullReferenceException をスローすることがわかりました。次の単体テストは、この問題を示しています。

[TestMethod]
[ExpectedException(typeof(NullReferenceException))]
public void GetData_Throws_NullReferenceException_When_EmployeeNo_Is_Not_Null_And_XmlEmployeeName_Is_Null()
{
    var inputWithoutEmployeeNo = GetElement(@"<input employeeNo='123'></input>");

    GetData(inputWithoutEmployeeNo);
}
于 2013-11-01T18:58:35.907 に答える
0

Moqの使用

using System;
using System.Xml;
using Moq;
using NUnit.Framework;

namespace MockXmlTest
{
    [TestFixture]
    public class MyServiceTests
    {
        private MockSetup _mockSetup;
        [SetUp]
        public void Init()
        {
            _mockSetup = MockSetup.HappySetup();
        }
        [Test]
        public void MyService_Should_Return_Guid()
        {
            //Arrange
            var myService = _mockSetup.MyService.Object;
            var id = 42;
            var expected = Guid.Empty.ToString();

            //Act
            var actual = myService.GetXml(id);

            //Assert
            Assert.AreEqual(expected, actual.FirstChild.InnerText);
        }
    }

    public class MyService : IMyService
    {
        public XmlDocument GetXml(int id)
        {
            var doc = new XmlDocument();
            //Do real stuff
            return doc;
        }
    }

    public interface IMyService
    {
        XmlDocument GetXml(int id);
    }

    public class MockSetup
    {
        public Mock<IMyService> MyService { get; set; }

        public MockSetup()
        {
            MyService = new Mock<IMyService>();
        }
        public static MockSetup HappySetup()
        {
            var mockSetup = new MockSetup();

            var mockDoc = CreateMockDoc();

            //Matches any id of an integer, returns a XmlDocument mock
            mockSetup.MyService.Setup(m => m.GetXml(It.IsAny<int>())).Returns(mockDoc);
            return mockSetup;
        }

        private static XmlDocument CreateMockDoc()
        {
            //<Main><MyGuid>00000000-0000-0000-0000-000000000000</MyGuid></Main>
            XmlDocument mockDoc = new XmlDocument();
            XmlElement el = (XmlElement)mockDoc.AppendChild(mockDoc.CreateElement("Main"));

            el.AppendChild(mockDoc.CreateElement("MyGuid")).InnerText = It.IsAny<Guid>().ToString();
            return mockDoc;
        }
    }
}
于 2020-01-24T20:54:59.447 に答える