我想测试的功能:
string theText = _resourceManager.GetString<MyApp.Localization
.MyTexts>(x => x.TheKeyAsString);
模板是一个包含textrexources的类。 TheKeyAsString是一个字符串,是获取正确文本的密钥。
我如何对此进行单元测试?
这是我所希望的工作。它不起作用:
Expression<Func<MyApp.Localization.MyTexts, string>> myExpression = x => x.TheKeyAsString;
A.CallTo(() => _resourceManager.GetString<MyApp.Localization.MyTexts>(
A<Expression<Func<MyApp.Localization.MyTexts, string>>>
.That.Matches(x => x == myExpression )))
.Returns("TheText");
当我像这样调用ResourceManager时,有人能告诉我如何设置FakeItEasy来提供“TheText”:
string theText = _resourceManager.GetString<MyApp.Localization.MyTexts>(
x => x.TheKeyAsString);
答案 0 :(得分:2)
根据你的解释,我不确定你真正想在这里测试什么。通常,您不会测试模拟/伪造对象,因为您只是将其配置为按照您的意愿运行。因此,如果_resourceManager
是假的,那么正确的测试将是您测试不同的组件,消费 _resourceManager
并调用其{ {1}}方法。
为此,测试可能如下所示:
GetString
由于这是在非常特定的测试场景中发生的,因此您很可能不需要关心将哪种表达式传递给// arrange
var resManager = A.Fake<IResourceManager>();
A.CallTo(() => resManager.GetString<MyTexts>(A<Expression<Func<MyTexts, string>>>.Ignored))
.Returns("Foo bar");
var testedObject = new ComponentYouWantToTest(resManager);
// act
var result = testedObject.DoSomething();
// assert
Assert.Equal("Foo bar", result.SomeProperty);
A.CallTo(() => resManager.GetString<MyTexts>(A<Expression<Func<MyTexts, string>>>.Ignored))
.MustHaveHappened(Repeated.AtLeast.Once);
方法。如果您希望使用不同的表达式多次调用该方法,则只需要这样做。
但是,在这种情况下,您需要注意不能使用GetString
比较两个表达式。因此,您的设置会失败,因为您将之前创建的==
与之后的myExpression
进行了比较。
如果你还想测试你的ComponentYouWantToTest
也用正确的表达式调用方法,例如检查它是否在lambda表达式中使用了正确的属性,那么你可以这样做:
// arrange
var myTexts = new MyTexts
{
EmailBody = "emailBody",
TheKeyAsString = "theKeyAsString",
};
var resManager = A.Fake<IResourceManager>();
A.CallTo(() => resManager.GetString<MyTexts>(A<Expression<Func<MyTexts, string>>>.Ignored))
.ReturnsLazily(((Expression<Func<MyTexts, string>>expr) => expr.Compile()(myTexts)));
var testedObject = new ComponentYouWantToTest(resManager);
// act
var result = testedObject.DoSomething();
// assert
Assert.Equal("emailBody", result.SomeProperty);
如果组件使用了除x => x.EmailBody
以外的其他键功能,则它现在不会从emailBody
实例获得myTexts
值。
答案 1 :(得分:0)
这里的问题是Expression<TDelegate>
没有实现相等。如果你这样做:
Expression<Func<int>> expr1 = () => 42;
Expression<Func<int>> expr2 = () => 42;
expr1
和expr2
不会被视为相同,即使它们相同。
所以像这样配置假:
A.CallTo(() => _resourceManager.GetString<MyApp.Localization.MyTexts>(x => x.TheKeyAsString))
.Returns("TheText");
(相当于您编写的配置,但更简单)
与_resourceManager.GetString<MyApp.Localization.MyTexts>(x => x.TheKeyAsString)
的实际调用不匹配,因为将传递表达式的不同实例。
要解决此问题,您需要一种方法来测试表达式是否相等。您可以比较表达式的文本表示,如下所示:
A.CallTo(() => _resourceManager.GetString<MyApp.Localization.MyTexts>(
A<Expression<Func<MyApp.Localization.MyTexts, string>>>
.That.Matches(x => x.ToString() == myExpression.ToString())))
.Returns("TheText");
相同的表达式将具有相同的文本表示,但可以想象不同的表达式也可以具有相同的文本表示,因此它不是万无一失的......