Ich versuche Unit-Test eine Methode, und es verwendet ein Wörterbuch zu einer verspotteten Methode, um Anhänge zu einer E-Mail hinzuzufügen. Der Test schlägt immer fehl, der Schritt durch alles scheint korrekt zu sein, aber die Assert
scheint das nicht zu bestätigen.Gleichheitsprüfung für Dictionary <string, Stream> mit xunit
Gibt es eine spezielle Art der Unit-Tests Wörterbücher im Allgemeinen, und würde das mit arbeiten für Setup ist für <string, Stream>
. Code ist unten, aber denke nicht, dass es irgendetwas damit zu tun hat, aber vielleicht etwas falsch eingerichtet hat, ich denke, ich vermisse etwas Offensichtliches.
[Fact]
public void Process_ShouldAttachCsvStreamWhenBuildingEmailMessage()
{
//Arrange
var fixture = new Fixture();
var settings = fixture.Create<Settings>();
var sutFixtures = new SUTFixtures(true);
var response = RemoteClientResponseHelper.GetMockHttpWebResponse(sutFixtures.Items);
//deal with attachement
var csv = sutFixtures.ToCsv();
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(csv);
var messageAttachments = new Dictionary<string, Stream> {{"MissingImages.csv", new MemoryStream(bytes)}};
var moqClientService = new Mock<IClientService>();
moqClientService.Setup(x => x.Call(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), null))
.Returns(response.Object);
Dictionary<string, Stream> attachmentsVerify = null;
var moqEmailService = new Mock<IEmailService>();
moqEmailService.Setup(
x =>
x.BuildMessage(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<bool>(), It.IsAny<Dictionary<string, Stream>>()))
.Callback<string, string, string, string, bool, Dictionary<string, Stream>>(
(to, from, subject, body, isHtml, attachments) =>
{
attachmentsVerify = attachments;
});
//Act
var sut = new MissingImageNotificationStep(moqClientService.Object, moqEmailService.Object, settings);
sut.Process(new MappingData() { Parts = sutFixtures.DataTable });
//Assert
moqEmailService.Verify(m => m.BuildMessage(It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<bool>(),
It.IsAny<Dictionary<string, Stream>>()), Times.Once());
Assert.Equal(messageAttachments, attachmentsVerify);
}
UPDATE
muss sehr faul gewesen sein, wie ich über eine benutzerdefinierte comparer dachte aber dachte, vielleicht war es schon etwas. Ich habe etwas funktioniert, für meinen Fall sowieso, mit Blick auf den Vergleich muss ich ein explizites Casting machen, was in meinem Fall in Ordnung ist, aber ein bisschen stinkt und deshalb benötigt mein Code einen Refactor, auch nicht sicher, ob GetHash irgendetwas in diesem Szenario tut Wenn dieser Code jemals außerhalb der Tests verwendet wird, werde ich das betrachten.
Individuelle Comparer
public class DictionaryComparer : IEqualityComparer<Dictionary<string, Stream>>
{
private readonly IEqualityComparer<Stream> _valueComparer;
public DictionaryComparer(IEqualityComparer<Stream> valueComparer = null)
{
this._valueComparer = valueComparer ?? EqualityComparer<Stream>.Default;
}
public bool Equals(Dictionary<string, Stream> x, Dictionary<string, Stream> y)
{
if (x.Count != y.Count)
return false;
if (x.Keys.Except(y.Keys).Any())
return false;
if (y.Keys.Except(x.Keys).Any())
return false;
foreach (var pair in x)
{
var xValue = pair.Value as MemoryStream;
var yValue = y[pair.Key] as MemoryStream;
if (xValue.Length != yValue.Length)
return false;
xValue.Position = 0;
yValue.Position = 0;
var xArray = xValue.ToArray();
var yArray = yValue.ToArray();
return xArray.SequenceEqual(yArray);
}
return true;
}
public int GetHashCode(Dictionary<string, Stream> obj)
{
unchecked
{
var hash = 17;
foreach (var key in obj.Keys)
{
hash = hash * 23 + key.GetHashCode();
}
return hash;
}
}
}
über XUnit Called
Assert.Equal(messageAttachments, attachmentsVerify, new DictionaryComparer());
Haben Sie darüber nachgedacht, die Methode Equal auf Dictionary zu überschreiben? –