[英]How to unit test an if-else statement in C#?
I want to test whether the if-else statements are executed, The "if" block returns the item from the dictionary/cache and returns the output, while "else" block adds the input inside the cache and returns an output 我想测试是否执行了if-else语句,“ if”块从字典/缓存中返回项目并返回输出,而“ else”块在缓存中添加输入并返回输出
An interface of IModifyBehavior with a method Apply IModifyBehavior的接口与方法Apply
I have this classes: 我有这个课程:
namespace Decorator
{
using System;
/// <summary>
/// Reverse Behavior
/// </summary>
public class ReverseBehavior : IModifyBehavior
{
/// <summary>
/// Applies the specified value.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>result</returns>
public string Apply(string value)
{
var result = string.Empty;
if (value != null)
{
char[] letters = value.ToCharArray();
Array.Reverse(letters);
result = new string(letters);
}
return result;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// Caching Decorator
/// </summary>
public class CachingDecorator : IModifyBehavior
{
/// <summary>
/// The behavior
/// </summary>
private IModifyBehavior behavior;
public CachingDecorator(IModifyBehavior behavior)
{
if (behavior == null)
{
throw new ArgumentNullException("behavior");
}
this.behavior = behavior;
}
private static Dictionary<string, string> cache = new Dictionary<string, string>();
/// <summary>
/// Applies the specified value.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>
/// value
/// </returns>
public string Apply(string value)
{
////Key = original value, Value = Reversed
var result = string.Empty;
//cache.Add("randel", "lednar");
if(cache.ContainsKey(value))
{
result = cache[value];
}
else
{
result = this.behavior.Apply(value);// = "reversed";
////Note:Add(key,value)
cache.Add(value, result);
}
return result;
}
}
}
Here's my current code for the test, the codes were able to passed the test, but I'm not sure if my implementation was correct: 这是我当前的测试代码,这些代码能够通过测试,但是我不确定我的实现是否正确:
[TestClass]
public class CachingDecoratorTest
{
private IModifyBehavior behavior;
[TestInitialize]
public void Setup()
{
this.behavior = new CachingDecorator(new ReverseBehavior());
}
[TestCleanup]
public void Teardown()
{
this.behavior = null;
}
[TestMethod]
public void Apply_Cached_ReturnsReversedCachedValue()
{
string actual = "randel";
////store it inside the cache
string cached = this.behavior.Apply(actual);
////call the function again, to test the else block statement
////Implement DRY principle next time
string expected = this.behavior.Apply(actual);
Assert.IsTrue(cached.Equals(expected));
}
[TestMethod]
public void Apply_NotCached_ReturnsReversed()
{
string actual = "randel";
string expected = "lednar";
Assert.AreEqual(expected, this.behavior.Apply(actual));
}
}
Sir/Ma'am your answers would be of great help. 先生/女士,您的回答会很有帮助。 Thank you++
谢谢++
The best way would be to use a mocking framework (like Moq, for instance) to create a fake IModifyBehaviour
object. 最好的方法是使用模拟框架(例如Moq)来创建伪造的
IModifyBehaviour
对象。
The Apply_NotCached_ReturnsReversed
test would then verify that the Apply
method of the mock object was called to generate the result. 然后,
Apply_NotCached_ReturnsReversed
测试将验证是否调用了模拟对象的Apply
方法来生成结果。 The Apply_Cached_ReturnsReversedCachedValue
test would check that the result was returned without calling the Apply
method of the mock object. Apply_Cached_ReturnsReversedCachedValue
测试将检查是否返回了结果,而不调用模拟对象的Apply
方法。
As it is, you test for the cached case doesn't actually prove that the result came from the cache. 照原样,您测试缓存的情况实际上并不能证明结果来自缓存。
First of all I would actually test the two clases in isolation, as proper units. 首先,我将单独测试两个分类,作为适当的单位。 Below I wrote up how I would test these.
下面我写了我将如何测试这些。 For this I'm using NUnit, and Moq (available in Nuget) as a mocking framework.
为此,我使用了NUnit和Moq (在Nuget中可用)作为模拟框架。 But you can just change the test attributes and use MSTest instead.
但是您可以更改测试属性,而改用MSTest。
For the reverse behavior I'm covering both a regular apply and applying to a null text: 对于相反的行为,我将介绍常规的套用和套用到空文本:
using System;
using System.Linq;
using Decorator;
using NUnit.Framework;
namespace StackOverflow.Tests.HowToTest
{
[TestFixture]
public class ReverseBehaviorTest
{
[Test]
public void Apply()
{
const string someText = "someText";
var target = new ReverseBehavior();
var result = target.Apply(someText);
Assert.AreEqual(someText.Reverse(), result);
}
[Test]
public void Apply_WhenNull()
{
var target = new ReverseBehavior();
var result = target.Apply(null);
Assert.AreEqual(String.Empty, result);
}
}
}
And for the CachingDecorator, the constructor's exception throwing, applying with caching and without: 对于CachingDecorator而言,构造函数的异常抛出将在没有缓存的情况下应用:
using System;
using Decorator;
using Moq;
using NUnit.Framework;
namespace StackOverflow.Tests.HowToTest
{
[TestFixture]
public class CachingDecoratorTest
{
[Test]
public void Constructor()
{
Assert.Throws(typeof(ArgumentNullException), () => new CachingDecorator(null));
}
[Test]
public void Apply_NotCached()
{
var internalBehaviorMock = new Mock<IModifyBehavior>();
internalBehaviorMock.Setup(x => x.Apply(It.IsAny<string>())).Returns<string>(y => y);
const string someText = "someText";
var target = new CachingDecorator(internalBehaviorMock.Object);
target.Apply(someText);
internalBehaviorMock.Verify(x => x.Apply(It.IsAny<string>()), Times.Once());
}
[Test]
public void Apply_Cached()
{
var internalBehaviorMock = new Mock<IModifyBehavior>();
internalBehaviorMock.Setup(x => x.Apply(It.IsAny<string>())).Returns<string>(y => y);
const string someOtherText = "someOtherText";
var target = new CachingDecorator(internalBehaviorMock.Object);
target.Apply(someOtherText);
target.Apply(someOtherText);
internalBehaviorMock.Verify(x => x.Apply(It.IsAny<string>()), Times.Once());
}
}
}
just try to set cache dictionary values in your testcase and check for count after calling Apply(string value) method. 只需尝试在测试用例中设置缓存字典值,然后在调用Apply(string value)方法后检查计数。
`
public void Apply_Cached_ReturnsReversedCachedValue()
{
Dictionary<string, string> cacheDict = new Dictionary<string, string>() { { "sometext", "txetemos" } };
string str = "sometext";
int dictionaryCountBeforeApply = cacheDict.Count();
//set value to static cache field using reflection, here dictionary count is 1
Type type = typeof(CachingDecorator);
FieldInfo cacheFieldInfo = type.GetField("cache", BindingFlags.NonPublic | BindingFlags.Static);
cacheFieldInfo.SetValue(decorator, cacheDict);
string result = decorator.Apply(str);
int dictionaryCountAfterApply = cacheDict.Count();
Assert.AreEqual(dictionaryCountAfterApply, dictionaryCountBeforeApply);
}
public void Apply_NotCached_ReturnsReversed()
{
Dictionary<string, string> cacheDict = new Dictionary<string, string>() { };
string str = "sometext";
int dictionaryCountBeforeApply = cacheDict.Count();
//set value to static cache field using reflection, here dictionary count is 0
Type type = typeof(CachingDecorator);
FieldInfo cacheFieldInfo = type.GetField("cache", BindingFlags.NonPublic | BindingFlags.Static);
cacheFieldInfo.SetValue(decorator, cacheDict);
string result = decorator.Apply(str);
int dictionaryCountAfterApply = cacheDict.Count();
Assert.AreNotEqual(dictionaryCountAfterApply, dictionaryCountBeforeApply);
}`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.