测试:
[TestMethod]
public void TestStringWithValidAndInvalid()
{
MockRepository mocks = new MockRepository();
ICentipedeCore mockCore = mocks.DynamicMock<ICentipedeCore>();
IPythonEngine pythonEngine = mocks.StrictMock<IPythonEngine>();
IPythonByteCode mockPythonByteCode = mocks.Stub<IPythonByteCode>();
mockCore.Stub(c => c.PythonEngine)
.Return(pythonEngine);
pythonEngine.Expect(e => e.Compile(Arg<String>.Is.Equal("\"String\""),
Arg<PythonByteCode.SourceCodeType>.Is.Anything))
.Return(mockPythonByteCode);
pythonEngine.Expect(e => e.Evaluate(Arg<IPythonByteCode>.Is.Equal(mockPythonByteCode),
Arg<PythonScope>.Is.Anything))
.Return(3);
pythonEngine.Expect(e => e.Compile(Arg<String>.Is.Equal("this is invalid python"),
Arg<PythonByteCode.SourceCodeType>.Is.Anything))
.Throw(new PythonParseException(mocks.Stub<Exception>()));
ActionWrapper testAction = new ActionWrapper(mockCore);
var original = @"{1+2} with {invalid python}";
var expected = "3 with {invalid python}";
var result = testAction.ParseStringForVariable(original); // ActionTest.cs: line 267
mocks.VerifyAll();
Assert.AreEqual(expected, result);
}
测试中的方法(由包装器公开):
protected String ParseStringForVariable([NotNull] String str)
{
IPythonEngine pythonEngine = GetCurrentCore().PythonEngine;
for (int i = 0; i < str.Length; i++)
{
if (str[i] != '{')
{
continue;
}
int opening = i;
foreach (var expression in from closing in str.IndexesWhere('}'.Equals)
where closing > opening
select new
{
Template = str.Substring(opening, closing - opening + 1),
Code = str.Substring(opening + 1, closing - opening - 1)
})
{
IPythonByteCode compiled;
try
{
compiled = pythonEngine.Compile(expression.Code, PythonByteCode.SourceCodeType.Expression);
}
catch (PythonParseException)
{
// not valid python, try next expression
continue;
}
dynamic r = pythonEngine.Evaluate(compiled);
String result = r.ToString(); // Action.cs: line 217, wrapped at ActionTest.cs: line 96
str = str.Replace(expression.Template, result);
break;
}
}
return str;
}
例外:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:无法对空引用执行运行时绑定
在dynamic r = pythonEngine.Evaluate(compiled);
r
为空后,该行会抛出异常。但我不知道为什么 - compiled
与mockPythonByteCode具有相同的值,pythonEngine是在测试中创建的模拟,而相同的调用在不同的方法中工作。这里唯一的区别是pythonEngine.Compile
在不同的输入上有两个期望,结果不同。
问题是,我有TestStringWithValidCode()
和TestStringWithInvalidCode()
,两者都运行良好,我合并为TestStringWithValidAndInvalid()
,所以每一半应该工作
答案 0 :(得分:1)
检查null会更加谨慎,因为由于代码的结构,当catch
发生且compiled
为空时它会运行碰巧发生的代码期望compiled
不会为空。
所以
变化:
catch (PythonParseException)
{
// not valid python, try next expression
continue;
}
dynamic r = pythonEngine.Evaluate(compiled);
到
catch (PythonParseException)
{
// not valid python, try next expression
continue;
}
if (compiled != null)
{
dynamic r = pythonEngine.Evaluate(compiled);
String result = r.ToString(); // Action.cs: line 217, wrapped at ActionTest.cs: line 96
str = str.Replace(expression.Template, result);
}
else
{
str="Exception Caught";
}
break;